void extractChannels( int argc, char* argv[] ) { pfs::DOMIO pfsio; static struct option cmdLineOptions[] = { { "help", no_argument, NULL, 'h' }, { NULL, 0, NULL, 0 } }; std::set<const char*, ltstr> keepChannels; int optionIndex = 0; while( 1 ) { int c = getopt_long (argc, argv, "h", cmdLineOptions, &optionIndex); if( c == -1 ) break; switch( c ) { case 'h': printHelp(); throw QuietException(); case '?': throw QuietException(); case ':': throw QuietException(); } } errorCheck( optind < argc, "At least one channel must be specified" ); for( ;optind < argc; optind++ ) keepChannels.insert( argv[optind] ); while( true ) { pfs::Frame *frame = pfsio.readFrame( stdin ); if( frame == NULL ) break; // No more frames { // Check if the listed channels exist std::set<const char*, ltstr>::iterator it; for( it = keepChannels.begin(); it != keepChannels.end(); it++ ) if( frame->getChannel( *it ) == NULL ) { fprintf( stderr, PROG_NAME " error: Channel %s does not exist\n", *it ); throw QuietException(); } } { // Remoe not listed channels pfs::ChannelIterator *it = frame->getChannels(); while( it->hasNext() ) { pfs::Channel *channel = it->getNext(); if( keepChannels.find(channel->getName() ) == keepChannels.end() ) frame->removeChannel( channel ); } } pfsio.writeFrame( frame, stdout ); pfsio.freeFrame( frame ); } }
static void errorCheck( bool condition, const char *string ) { if( !condition ) { fprintf( stderr, PROG_NAME " error: %s\n", string ); throw QuietException(); } }
int ClientConnection::LoadConnection_global(char *fname, bool fFromDialog,bool default_file) { GetPrivateProfileString("connection", "host", "", m_host, MAX_HOST_NAME_LEN, fname); m_port = GetPrivateProfileInt("connection", "port", 0, fname); GetPrivateProfileString("connection", "proxyhost", "", m_proxyhost, MAX_HOST_NAME_LEN, fname); m_proxyport = GetPrivateProfileInt("connection", "proxyport", 0, fname); m_fUseProxy = GetPrivateProfileInt("options", "UseProxy", 0, fname) ? true : false; char buf[32]; m_encPasswd[0] = '\0'; if (GetPrivateProfileString("connection", "password", "", buf, 32, fname) > 0) { for (int i = 0; i < MAXPWLEN; i++) { int x = 0; sscanf(buf+i*2, "%2x", &x); m_encPasswd[i] = (unsigned char) x; } } // The Connection Profile ".vnc" has been required from Connection Session Dialog Box // Load the rest of params char optionfile[MAX_PATH]; char *tempvar=NULL; tempvar = getenv( "TEMP" ); if (tempvar) strcpy(optionfile,tempvar); else strcpy(optionfile,""); strcat(optionfile,"\\options.vnc"); if (strcmp(m_host, "") == 0 || strcmp(fname,optionfile)==0) { // Load the rest of params strcpy(m_opts.m_proxyhost,m_proxyhost); m_opts.m_proxyport=m_proxyport; m_opts.m_fUseProxy=m_fUseProxy; m_opts.Load(fname); m_opts.Register(); // Then display the session dialog to get missing params again SessionDialog sessdlg(&m_opts, this, m_pDSMPlugin); //sf@2002 if (!sessdlg.DoDialog_global()) { throw QuietException(""); } _tcsncpy(m_host, sessdlg.m_host_dialog, MAX_HOST_NAME_LEN); m_port = sessdlg.m_port; _tcsncpy(m_proxyhost, sessdlg.m_proxyhost, MAX_HOST_NAME_LEN); m_proxyport = sessdlg.m_proxyport; m_fUseProxy = sessdlg.m_fUseProxy; }; //EndAaronP return 0; }
BOOL CALLBACK AuthDialog::DlgProc( HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam ) { // This is a static method, so we don't know which instantiation we're // dealing with. But we can get a pseudo-this from the parameter to // WM_INITDIALOG, which we therafter store with the window and retrieve // as follows: AuthDialog *_this = (AuthDialog *) GetWindowLong(hwnd, GWL_USERDATA); switch (uMsg) { case WM_INITDIALOG: { SetWindowLong(hwnd, GWL_USERDATA, lParam); _this = (AuthDialog *) lParam; CentreWindow(hwnd); return TRUE; } case WM_COMMAND: switch (LOWORD(wParam)) { case IDOK: { UINT res= GetDlgItemText( hwnd, IDC_PASSWD_EDIT, _this->m_passwd, 256); EndDialog(hwnd, TRUE); return TRUE; } case IDCANCEL: EndDialog(hwnd, FALSE); throw QuietException("User canceled connection."); return TRUE; } break; case WM_DESTROY: EndDialog(hwnd, FALSE); return TRUE; } return 0; }
void readFrames( int argc, char* argv[] ) { pfs::DOMIO pfsio; bool verbose = false; // Parse command line parameters static struct option cmdLineOptions[] = { { "help", no_argument, NULL, 'h' }, { "verbose", no_argument, NULL, 'v' }, { NULL, 0, NULL, 0 } }; static const char optstring[] = "hv"; pfs::FrameFileIterator it( argc, argv, "rb", NULL, NULL, optstring, cmdLineOptions ); int optionIndex = 0; while( 1 ) { int c = getopt_long (argc, argv, optstring, cmdLineOptions, &optionIndex); if( c == -1 ) break; switch( c ) { case 'h': printHelp(); throw QuietException(); case 'v': verbose = true; break; case '?': throw QuietException(); case ':': throw QuietException(); } } GDALAllRegister(); GDALDataset *poDataset; GDALRasterBand *poBand; double adfGeoTransform[6]; size_t nBlockXSize, nBlockYSize, nBands; int bGotMin, bGotMax; double adfMinMax[2]; float *pafScanline; while( true ) { pfs::FrameFile ff = it.getNextFrameFile(); if( ff.fh == NULL ) break; // No more frames it.closeFrameFile( ff ); VERBOSE_STR << "reading file '" << ff.fileName << "'" << std::endl; if( !( poDataset = (GDALDataset *) GDALOpen( ff.fileName, GA_ReadOnly ) ) ) { std::cerr << "input does not seem to be in a format supported by GDAL" << std::endl; throw QuietException(); } VERBOSE_STR << "GDAL driver: " << poDataset->GetDriver()->GetDescription() << " / " << poDataset->GetDriver()->GetMetadataItem( GDAL_DMD_LONGNAME ) << std::endl; nBlockXSize = poDataset->GetRasterXSize(); nBlockYSize = poDataset->GetRasterYSize(); nBands = poDataset->GetRasterCount(); VERBOSE_STR << "Data size " << nBlockXSize << "x" << nBlockYSize << "x" << nBands << std::endl; if( poDataset->GetProjectionRef() ) { VERBOSE_STR << "Projection " << poDataset->GetProjectionRef() << std::endl; } if( poDataset->GetGeoTransform( adfGeoTransform ) == CE_None ) { VERBOSE_STR << "Origin = (" << adfGeoTransform[0] << ", " << adfGeoTransform[3] << ")" << std::endl; VERBOSE_STR << "Pixel Size = (" << adfGeoTransform[1] << ", " << adfGeoTransform[5] << ")" << std::endl; } if( nBlockXSize==0 || nBlockYSize==0 || ( SIZE_MAX / nBlockYSize < nBlockXSize ) || ( SIZE_MAX / (nBlockXSize * nBlockYSize ) < 4 ) ) { std::cerr << "input data has invalid size" << std::endl; throw QuietException(); } if( !(pafScanline = (float *) CPLMalloc( sizeof(float) * nBlockXSize ) ) ) { std::cerr << "not enough memory" << std::endl; throw QuietException(); } pfs::Frame *frame = pfsio.createFrame( nBlockXSize, nBlockYSize ); pfs::Channel *C[nBands]; char channel_name[32]; frame->getTags()->setString( "X-GDAL_DRIVER_SHORTNAME", poDataset->GetDriver()->GetDescription() ); frame->getTags()->setString( "X-GDAL_DRIVER_LONGNAME", poDataset->GetDriver()->GetMetadataItem( GDAL_DMD_LONGNAME ) ); frame->getTags()->setString( "X-PROJECTION", poDataset->GetProjectionRef() ); if( poDataset->GetGeoTransform( adfGeoTransform ) == CE_None ) { frame->getTags()->setString( "X-ORIGIN_X", stringify(adfGeoTransform[0]).c_str() ); frame->getTags()->setString( "X-ORIGIN_Y", stringify(adfGeoTransform[3]).c_str() ); frame->getTags()->setString( "X-PIXEL_WIDTH", stringify(adfGeoTransform[1]).c_str() ); frame->getTags()->setString( "X-PIXEL_HEIGHT", stringify(adfGeoTransform[5]).c_str() ); } for ( size_t band = 1; band <= nBands; band++) { size_t nBandXSize, nBandYSize; VERBOSE_STR << "Band " << band << ": " << std::endl; snprintf( channel_name, 32, "X-GDAL%zu", band ); C[band - 1] = frame->createChannel( channel_name ); poBand = poDataset->GetRasterBand( band ); nBandXSize = poBand->GetXSize(); nBandYSize = poBand->GetYSize(); VERBOSE_STR << " " << nBandXSize << "x" << nBandYSize << std::endl; if( nBandXSize != (int)nBlockXSize || nBandYSize != (int)nBlockYSize ) { std::cerr << "data in band " << band << " has different size" << std::endl; throw QuietException(); } VERBOSE_STR << " Type " << GDALGetDataTypeName( poBand->GetRasterDataType() ) << ", " << "Color Interpretation " << GDALGetColorInterpretationName( poBand->GetColorInterpretation() ) << std::endl; adfMinMax[0] = poBand->GetMinimum( &bGotMin ); adfMinMax[1] = poBand->GetMaximum( &bGotMax ); if( ! (bGotMin && bGotMax) ) { GDALComputeRasterMinMax((GDALRasterBandH)poBand, TRUE, adfMinMax); } VERBOSE_STR << " Min " << adfMinMax[0] << ", Max " << adfMinMax[1] << std::endl; C[band - 1]->getTags()->setString( "X-TYPE", GDALGetDataTypeName( poBand->GetRasterDataType() ) ); C[band - 1]->getTags()->setString( "X-COLOR_INTERPRETATION", GDALGetColorInterpretationName( poBand->GetColorInterpretation() ) ); C[band - 1]->getTags()->setString( "X-MIN", stringify(adfMinMax[0]).c_str() ); C[band - 1]->getTags()->setString( "X-MAX", stringify(adfMinMax[1]).c_str() ); for( size_t y = 0; y < nBlockYSize; y++ ) { if( poBand->RasterIO( GF_Read, 0, y, nBlockXSize, 1, pafScanline, nBlockXSize, 1, GDT_Float32, 0, 0) != CE_None ) { std::cerr << "input error" << std::endl; throw QuietException(); } memcpy( C[band - 1]->getRawData() + y * nBlockXSize, pafScanline, nBlockXSize * sizeof(float) ); } } CPLFree( pafScanline ); GDALClose( poDataset ); const char *fileNameTag = strcmp( "-", ff.fileName )==0 ? "stdin" : ff.fileName; frame->getTags()->setString( "FILE_NAME", fileNameTag ); pfsio.writeFrame( frame, stdout ); pfsio.freeFrame( frame ); } }
// returns zero if successful int ClientConnection::LoadConnection(char *fname, bool fFromDialog,bool default_file) { // The Connection Profile ".vnc" has been required from Connection Session Dialog Box if (fFromDialog) { char tname[_MAX_FNAME + _MAX_EXT]; ofnInit(); ofn.hwndOwner = m_hSessionDialog; ofn.lpstrFile = fname; ofn.lpstrFileTitle = tname; ofn.Flags = OFN_HIDEREADONLY; // Open the FileSelection Dialog boxq if (GetOpenFileName(&ofn) == 0) return -1; } if (GetPrivateProfileString("connection", "host", "", m_host, MAX_HOST_NAME_LEN, fname) == 0) { //AaronP // MessageBox(m_hwnd, sz_K5, sz_K6, MB_ICONERROR | MB_OK | MB_SETFOREGROUND | MB_TOPMOST); // return -1; //EndAaronP } if ( (m_port = GetPrivateProfileInt("connection", "port", 0, fname)) == 0) { // //MessageBox(m_hwnd, sz_K7, sz_K6, MB_ICONERROR | MB_OK | MB_SETFOREGROUND | MB_TOPMOST); // in case options.vnc does not exist return to normal menu return -1; } GetPrivateProfileString("connection", "proxyhost", "", m_proxyhost, MAX_HOST_NAME_LEN, fname); m_proxyport = GetPrivateProfileInt("connection", "proxyport", 0, fname); m_fUseProxy = GetPrivateProfileInt("options", "UseProxy", 0, fname); char buf[32]; m_encPasswd[0] = '\0'; if (GetPrivateProfileString("connection", "password", "", buf, 32, fname) > 0) { for (int i = 0; i < MAXPWLEN; i++) { int x = 0; sscanf(buf+i*2, "%2x", &x); m_encPasswd[i] = (unsigned char) x; } } // The Connection Profile ".vnc" has been required from Connection Session Dialog Box // Load the rest of params char optionfile[MAX_PATH]; char *tempvar=NULL; tempvar = getenv( "TEMP" ); if (tempvar) strcpy(optionfile,tempvar); else strcpy(optionfile,""); strcat(optionfile,"\\options.vnc"); // if (fFromDialog) { m_opts.Load(fname); m_opts.Register(); } //AaronP //else if (strcmp(m_host, "") == 0 || strcmp(fname,optionfile)==0) { // Load the rest of params strcpy(m_opts.m_proxyhost,m_proxyhost); m_opts.m_proxyport=m_proxyport; m_opts.m_fUseProxy=m_fUseProxy; m_opts.Load(fname); m_opts.Register(); // Then display the session dialog to get missing params again SessionDialog sessdlg(&m_opts, this, m_pDSMPlugin); //sf@2002 if (!sessdlg.DoDialog()) { throw QuietException(""); } _tcsncpy(m_host, sessdlg.m_host_dialog, MAX_HOST_NAME_LEN); m_port = sessdlg.m_port; _tcsncpy(m_proxyhost, sessdlg.m_proxyhost, MAX_HOST_NAME_LEN); m_proxyport = sessdlg.m_proxyport; m_fUseProxy = sessdlg.m_fUseProxy; }; //EndAaronP return 0; }
void clampFrames( int argc, char* argv[] ) { pfs::DOMIO pfsio; float clampMin = 0.0001; // default: 10^-4 float clampMax = 100000000; // default: 10^8 bool verbose = false; bool opt_percentile = false; bool opt_zeromode = false; bool opt_rgbmode = false; static struct option cmdLineOptions[] = { { "help", no_argument, NULL, 'h' }, { "verbose", no_argument, NULL, 'v' }, { "percentile", no_argument, NULL, 'p' }, { "zero", no_argument, NULL, 'z' }, { "rgb", no_argument, NULL, 'r' }, { "min", required_argument, NULL, 'n' }, { "max", required_argument, NULL, 'x' }, { NULL, 0, NULL, 0 } }; int optionIndex = 0; while( 1 ) { int c = getopt_long (argc, argv, "hvpz", cmdLineOptions, &optionIndex); if( c == -1 ) break; switch( c ) { case 'h': printHelp(); throw QuietException(); case 'v': verbose = true; break; case 'p': opt_percentile = true; break; case 'z': opt_zeromode = true; break; case 'r': opt_rgbmode = true; break; case 'n': clampMin = (float)strtod( optarg, NULL ); break; case 'x': clampMax = (float)strtod( optarg, NULL ); break; case '?': throw QuietException(); case ':': throw QuietException(); } } // check if clamping parameters make sense if( opt_percentile ) { clampMin = (clampMin>1e-3) ? clampMin : 1e-3; clampMax = (clampMax<1) ? clampMax : 0.999f; if( clampMin >= clampMax ) throw pfs::Exception("incorrect clamping range for percentile mode"); } else { clampMin = (clampMin>1e-4) ? clampMin : 1e-4; clampMax = (clampMax<1e8) ? clampMax : 1e8; if( clampMin >= clampMax ) throw pfs::Exception("incorrect clamping range"); } if( verbose ) { if( opt_rgbmode ) fprintf(stderr, "Clamping in RGB color space.\n"); if( opt_zeromode ) fprintf(stderr, "Values out of clamp range will be set to zero.\n"); if( opt_percentile ) fprintf( stderr, "Clamping channels to [%g, %g] percentile.\n", clampMin, clampMax ); else fprintf( stderr, "Clamping channels to [%g, %g] range.\n", clampMin, clampMax ); } while( true ) { pfs::Frame *frame = pfsio.readFrame( stdin ); if( frame == NULL ) break; // No more frames pfs::Channel *X, *Y, *Z; frame->getXYZChannels( X, Y, Z ); if( X != NULL ) { // Color, XYZ if( opt_rgbmode ) pfs::transformColorSpace( pfs::CS_XYZ, X, Y, Z, pfs::CS_RGB, X, Y, Z ); clamp( X, clampMin, clampMax, opt_percentile, opt_zeromode ); clamp( Y, clampMin, clampMax, opt_percentile, opt_zeromode ); clamp( Z, clampMin, clampMax, opt_percentile, opt_zeromode ); if( opt_rgbmode ) pfs::transformColorSpace( pfs::CS_RGB, X, Y, Z, pfs::CS_XYZ, X, Y, Z ); } else if( (Y = frame->getChannel( "Y" )) != NULL ) { clamp( Y, clampMin, clampMax, opt_percentile, opt_zeromode ); } else throw pfs::Exception( "Missing X, Y, Z channels in the PFS stream" ); pfsio.writeFrame( frame, stdout ); pfsio.freeFrame( frame ); } }
void resizeFrames( int argc, char* argv[] ) { pfs::DOMIO pfsio; float ratio = -1; int xSize = -1; int ySize = -1; int minX = -1; int maxX = -1; int minY = -1; int maxY = -1; bool verbose = false; ResampleFilter *filter = NULL; static struct option cmdLineOptions[] = { { "help", no_argument, NULL, 'h' }, { "verbose", no_argument, NULL, 'v' }, { "x", required_argument, NULL, 'x' }, { "y", required_argument, NULL, 'y' }, { "maxx", required_argument, NULL, '1' }, { "maxy", required_argument, NULL, '2' }, { "minx", required_argument, NULL, '3' }, { "miny", required_argument, NULL, '4' }, { "ratio", required_argument, NULL, 'r' }, { "filter", required_argument, NULL, 'f' }, { NULL, 0, NULL, 0 } }; int optionIndex = 0; while( 1 ) { int c = getopt_long (argc, argv, "x:y:r:f:", cmdLineOptions, &optionIndex); if( c == -1 ) break; switch( c ) { case 'h': printHelp(); throw QuietException(); case 'v': verbose = true; break; case 'x': xSize = getIntParam( optarg, "x" ); break; case 'y': ySize = getIntParam( optarg, "y" ); break; case 'r': ratio = getFloatParam( optarg, "ratio" ); break; case '1': maxX = getIntParam( optarg, "maxx" ); break; case '2': maxY = getIntParam( optarg, "maxy" ); break; case '3': minX = getIntParam( optarg, "minx" ); break; case '4': minY = getIntParam( optarg, "miny" ); break; case 'f': if( !strcasecmp( optarg, "LINEAR" ) ) { filter = new LinearFilter(); } else if( !strcasecmp( optarg, "MITCHELL" ) ) { filter = new MitchellFilter(); } else if( !strcasecmp( optarg, "BOX" ) ) { filter = new BoxFilter(); } else { throw pfs::Exception( "Unknown filter. Possible values: LINEAR, BOX, MITCHELL" ); } break; case '?': throw QuietException(); case ':': throw QuietException(); } } if( filter == NULL ) filter = new LinearFilter(); bool isMinMax = (minX!=-1) || (maxX!=-1) || (minY!=-1) || (maxY!=-1); errorCheck( (minX==-1 || maxX == -1 || minX <= maxX) && (minY==-1 || maxY==-1 || minY <= maxY), "Min value must be lower than max value" ); errorCheck( (ratio != -1) ^ (xSize != -1 || ySize != -1) ^ isMinMax, "Specify either size or ratio or min/max sizes" ); errorCheck( ratio == -1 || ratio > 0 , "Wrong scaling ratio" ); // bool firstFrame = true; pfs::Frame *resizedFrame = NULL; while( true ) { pfs::Frame *frame = pfsio.readFrame( stdin ); if( frame == NULL ) break; // No more frames pfs::Channel *X, *Y, *Z; frame->getXYZChannels( X, Y, Z ); // pfs::Channel *dX, *dY, *dZ; // if( firstFrame ) { int new_x, new_y; if( ratio != -1 ) { new_x = (int)(frame->getWidth()*ratio); new_y = (int)(frame->getHeight()*ratio); } else { if( isMinMax ) { // Min/max sizes given new_x = frame->getWidth(); new_y = frame->getHeight(); float mm_ratio = (float)new_x/(float)new_y; if( minX != -1 && new_x < minX ) { new_x = minX; new_y = (int)((float)new_x/mm_ratio); } if( minY != -1 && new_y < minY ) { new_y = minY; new_x = (int)((float)new_y*mm_ratio); } if( maxX != -1 && new_x > maxX ) { new_x = maxX; new_y = (int)((float)new_x/mm_ratio); } if( maxY != -1 && new_y > maxY ) { new_y = maxY; new_x = (int)((float)new_y*mm_ratio); } } else { // Size given new_x = xSize; new_y = ySize; if( new_x == -1 ) new_x = (int)((float)frame->getWidth() * (float)ySize / (float)frame->getHeight()); else if( new_y == -1 ) new_y = (int)((float)frame->getHeight() * (float)xSize / (float)frame->getWidth()); } } errorCheck( new_x > 0 && new_y > 0 && new_x <= 65536 && new_y <= 65536, "Wrong frame size" ); errorCheck( ((frame->getWidth() <= new_x) && (frame->getHeight() <= new_y)) || ((frame->getWidth() >= new_x) && (frame->getHeight() >= new_y)), "Can upsample / downsample image only in both dimensions simultaneously" ); if( verbose ) fprintf( stderr, "New size: %d x %d \n", new_x, new_y ); resizedFrame = pfsio.createFrame( new_x, new_y ); // firstFrame = false; // } pfs::ChannelIterator *it = frame->getChannels(); while( it->hasNext() ) { pfs::Channel *originalCh = it->getNext(); pfs::Channel *newCh = resizedFrame->createChannel( originalCh->getName() ); resampleArray( originalCh, newCh, filter ); } pfs::copyTags( frame, resizedFrame ); pfsio.writeFrame( resizedFrame, stdout ); pfsio.freeFrame( frame ); } pfsio.freeFrame( resizedFrame ); delete filter; }
void applyAbsoluteOnFrames( int argc, char* argv[] ) { pfs::DOMIO pfsio; float destY = 1.0f; float srcY = 1.0f; bool verbose = false; static struct option cmdLineOptions[] = { { "help", no_argument, NULL, 'h' }, { "verbose", no_argument, NULL, 'v' }, { NULL, 0, NULL, 0 } }; int optionIndex = 0; while( 1 ) { int c = getopt_long (argc, argv, "", cmdLineOptions, &optionIndex); if( c == -1 ) break; switch( c ) { case 'h': printHelp(); throw QuietException(); case 'v': verbose = true; break; case '?': throw QuietException(); case ':': throw QuietException(); } } if( optind == argc ) throw pfs::Exception( "Destination luminance level <dest Y> must be specified" ); if( optind < (argc - 2) ) throw pfs::Exception( "Too many arguments" ); destY = strtof( argv[optind++], NULL ); if( optind != argc ) srcY = strtof( argv[optind++], NULL ); VERBOSE_STR << "rescale luminance to: " << destY << std::endl; if( srcY != 1.0f ) VERBOSE_STR << "from: " << srcY << std::endl; float multY = destY/srcY; while( true ) { pfs::Frame *frame = pfsio.readFrame( stdin ); if( frame == NULL ) break; // No more frames const char *lumType = frame->getTags()->getString( "LUMINANCE" ); if( lumType != NULL && !strcmp( lumType, "ABSOLUTE" ) ) { VERBOSE_STR << "luminance is already absolute, skipping frame."; } else { pfs::Channel *X, *Y, *Z; frame->getXYZChannels( X, Y, Z ); if( X != NULL ) { // Color, XYZ if( lumType != NULL && !strcmp( lumType, "DISPLAY" ) ) { VERBOSE_STR << "converting from display-referred to linear luminance."; pfs::transformColorSpace( pfs::CS_XYZ, X, Y, Z, pfs::CS_RGB, X, Y, Z ); pfs::transformColorSpace( pfs::CS_SRGB, X, Y, Z, pfs::CS_XYZ, X, Y, Z ); } multiplyArray( X, X, multY ); multiplyArray( Y, Y, multY ); multiplyArray( Z, Z, multY ); } else if( (Y = frame->getChannel( "Y" )) != NULL ) { // Luminance only if( lumType != NULL && !strcmp( lumType, "DISPLAY" ) ) throw pfs::Exception( PROG_NAME ": Cannot handle gray-level display-referred images." ); multiplyArray( Y, Y, multY ); } else throw pfs::Exception( "Missing color channels in the PFS stream" ); frame->getTags()->setString("LUMINANCE", "ABSOLUTE"); } pfsio.writeFrame( frame, stdout ); pfsio.freeFrame( frame ); } }
void readFrames( int argc, char* argv[] ) { pfs::DOMIO pfsio; bool verbose = false; bool opt_linear=false; float absoluteMaxLum = 0; // Parse command line parameters static struct option cmdLineOptions[] = { { "help", no_argument, NULL, 'h' }, { "verbose", no_argument, NULL, 'v' }, { "linear", no_argument, NULL, 'l' }, { "absolute", required_argument, NULL, 'a' }, { NULL, 0, NULL, 0 } }; static const char optstring[] = "lhva:"; pfs::FrameFileIterator it( argc, argv, "rb", NULL, NULL, optstring, cmdLineOptions ); int optionIndex = 0; while( 1 ) { int c = getopt_long (argc, argv, optstring, cmdLineOptions, &optionIndex); if( c == -1 ) break; switch( c ) { case 'h': printHelp(); throw QuietException(); case 'v': verbose = true; break; case 'l': opt_linear = true; break; case 'a': absoluteMaxLum = (float)strtod( optarg, NULL ); break; case '?': throw QuietException(); case ':': throw QuietException(); } } if( absoluteMaxLum != 0 && opt_linear ) throw pfs::Exception( "'absolute' and 'linear' are conflicting options" ); if( absoluteMaxLum < 0 ) throw pfs::Exception( "maximum absolute luminance must be > 0" ); VERBOSE_STR << "linearize input image: " << ((opt_linear || absoluteMaxLum!=0) ? "yes" : "no") << std::endl; if( absoluteMaxLum != 0 ) VERBOSE_STR << "maximum absolute luminance: " << absoluteMaxLum << std::endl; while( true ) { pfs::FrameFile ff = it.getNextFrameFile(); if( ff.fh == NULL ) break; // No more frames it.closeFrameFile( ff ); VERBOSE_STR << "reading file '" << ff.fileName << "'" << std::endl; Magick::Image imImage( ff.fileName ); VERBOSE_STR << "input image gamma: " << imImage.gamma() << std::endl; bool hasAlpha = imImage.matte(); if( hasAlpha ) VERBOSE_STR << "alpha channel found" << std::endl; pfs::Frame *frame = pfsio.createFrame( imImage.columns(), imImage.rows() ); pfs::Channel *X, *Y, *Z; frame->createXYZChannels( X, Y, Z ); pfs::Channel *alpha = NULL; if( hasAlpha ) alpha = frame->createChannel( "ALPHA" ); // Copy line by line to pfs::Frame int pixInd = 0; const float maxValue = (float)(1<<QuantumDepth) - 1; for( int r = 0; r < imImage.rows(); r++ ) { const Magick::PixelPacket *pixels = imImage.getConstPixels( 0, r, imImage.columns(), 1 ); for( int c = 0; c < imImage.columns(); c++ ) { (*X)(pixInd) = (float)pixels[c].red / maxValue; (*Y)(pixInd) = (float)pixels[c].green / maxValue; (*Z)(pixInd) = (float)pixels[c].blue / maxValue; if( alpha != NULL ) (*alpha)(pixInd) = (float)pixels[c].opacity / maxValue; pixInd++; } } // Linearize data is necessary if( opt_linear || absoluteMaxLum != 0 ) { pfs::transformColorSpace( pfs::CS_SRGB, X, Y, Z, pfs::CS_XYZ, X, Y, Z ); if( absoluteMaxLum != 0 ) { // Rescale to absolute luminance level const int pixCount = X->getWidth()*X->getHeight(); for( int i = 0; i < pixCount; i++ ) { (*X)(i) *= absoluteMaxLum; (*Y)(i) *= absoluteMaxLum; (*Z)(i) *= absoluteMaxLum; } frame->getTags()->setString("LUMINANCE", "ABSOLUTE"); } else frame->getTags()->setString("LUMINANCE", "RELATIVE"); } else { pfs::transformColorSpace( pfs::CS_RGB, X, Y, Z, pfs::CS_XYZ, X, Y, Z ); frame->getTags()->setString("LUMINANCE", "DISPLAY"); } // This is the luminance / luma perceived as reference white // Some tone-mappers may need this frame->getTags()->setString("WHITE_Y", "1"); const char *fileNameTag = strcmp( "-", ff.fileName )==0 ? "stdin" : ff.fileName; frame->getTags()->setString( "FILE_NAME", fileNameTag ); char strbuf[3]; snprintf( strbuf, 3, "%d", (int)imImage.depth() ); frame->getTags()->setString("BITDEPTH", strbuf ); pfsio.writeFrame( frame, stdout ); pfsio.freeFrame( frame ); } }