SoImageWriter.cc

Go to the documentation of this file.
00001 //
00002 // ********************************************************************
00003 // * License and Disclaimer                                           *
00004 // *                                                                  *
00005 // * The  Geant4 software  is  copyright of the Copyright Holders  of *
00006 // * the Geant4 Collaboration.  It is provided  under  the terms  and *
00007 // * conditions of the Geant4 Software License,  included in the file *
00008 // * LICENSE and available at  http://cern.ch/geant4/license .  These *
00009 // * include a list of copyright holders.                             *
00010 // *                                                                  *
00011 // * Neither the authors of this software system, nor their employing *
00012 // * institutes,nor the agencies providing financial support for this *
00013 // * work  make  any representation or  warranty, express or implied, *
00014 // * regarding  this  software system or assume any liability for its *
00015 // * use.  Please see the license in the file  LICENSE  and URL above *
00016 // * for the full disclaimer and the limitation of liability.         *
00017 // *                                                                  *
00018 // * This  code  implementation is the result of  the  scientific and *
00019 // * technical work of the GEANT4 collaboration.                      *
00020 // * By using,  copying,  modifying or  distributing the software (or *
00021 // * any work based  on the software)  you  agree  to acknowledge its *
00022 // * use  in  resulting  scientific  publications,  and indicate your *
00023 // * acceptance of all terms of the Geant4 Software license.          *
00024 // ********************************************************************
00025 //
00026 #ifdef G4VIS_BUILD_OI_DRIVER
00027 
00028 /*----------------------------HEPVis----------------------------------------*/
00029 /*                                                                          */
00030 /* Node:             SoImageWriter                                          */
00031 /* Author:           Guy Barrand                                            */
00032 /*                                                                          */
00033 /*--------------------------------------------------------------------------*/
00034 
00035 // this :
00036 #include <HEPVis/nodes/SoImageWriter.h>
00037 
00038 #include <Inventor/errors/SoDebugError.h>
00039 #include <Inventor/elements/SoViewportRegionElement.h>
00040 #include <Inventor/actions/SoGLRenderAction.h>
00041 
00042 #include <HEPVis/SbGL.h>
00043 #include <HEPVis/SbPainterPS.h>
00044 //#include <HEPVis/SbGIF.h>
00045 
00046 #include <stdlib.h>
00047 
00048 typedef struct {
00049   unsigned char red;
00050   unsigned char green;
00051   unsigned char blue;
00052 } Pixel;
00053 typedef unsigned char Uchar;
00054 
00055 //static void getImagePixels(int,int,float*,int&,
00056 //                         Uchar*&,Uchar*&,Uchar*&,Uchar*&);
00057 
00058 static int sWidth = 0;
00059 static int sHeight = 0;
00060 static float* sImage = 0;
00061 static int getRGB(unsigned int,unsigned int,double&,double&,double&);
00062 
00063 SO_NODE_SOURCE(SoImageWriter)
00065 void SoImageWriter::initClass (
00066 )
00069 {
00070   SO_NODE_INIT_CLASS(SoImageWriter,SoNode,"Node");
00071 }
00073 SoImageWriter::SoImageWriter(
00074 )
00075 :fEnabled(FALSE)
00076 ,fStatus(FALSE)
00079 {
00080   SO_NODE_CONSTRUCTOR(SoImageWriter);
00081   //SO_NODE_ADD_FIELD(format,(POST_SCRIPT));
00082   SO_NODE_ADD_FIELD(fileName,("out.ps"));
00083   
00084   //SO_NODE_DEFINE_ENUM_VALUE(Format,POST_SCRIPT);
00085   //SO_NODE_DEFINE_ENUM_VALUE(Format,GIF);
00086   
00087   //SO_NODE_SET_SF_ENUM_TYPE(format,Format);
00088 }
00090 SoImageWriter::~SoImageWriter (
00091 )
00094 {
00095 }
00097 void SoImageWriter::enable(
00098 )
00101 {
00102   fEnabled = TRUE;
00103 }
00105 void SoImageWriter::disable(
00106 )
00109 {
00110   fEnabled = FALSE;
00111 }
00113 SbBool SoImageWriter::getStatus(
00114 ) const
00117 {
00118   return fStatus;
00119 }
00121 void SoImageWriter::GLRender(
00122  SoGLRenderAction* aAction
00123 )
00126 {
00127   fStatus = FALSE;
00128   //printf("debug : SoImageWriter::GLRender : enabled : %d\n",fEnabled);
00129   if(!fEnabled) return;
00130   SbViewportRegion vpr = SoViewportRegionElement::get(aAction->getState());
00131   const SbVec2s& win = vpr.getWindowSize();
00132   int w = win[0];
00133   int h = win[1];
00134   if((w*h)<=0) {
00135     SoDebugError::postInfo("SoImageWriter::GLRender","null area window !");
00136     return;
00137   }
00138 
00139   int x = 0;
00140   int y = 0;
00141   int s = 3 * w * h;
00142   float* image = new float[s];
00143   if(!image) return;
00144 
00145   //printf("debug : SoImageWriter::GLRender : %d %d %d %d\n",x,y,w,h);
00146 
00147   //glReadPixels(x,y,w,h,GL_RGB,GL_UNSIGNED_BYTE,image); Don't work !
00148   glReadPixels(x,y,w,h,GL_RGB,GL_FLOAT,image);
00149 
00150   //Format fm = (Format)format.getValue();
00151   //if(fm==GIF) {  
00152 /*
00153     FILE* file = fopen(fileName.getValue().getString(),"wb");
00154     if(!file) {
00155       SoDebugError::postInfo("SoImageWriter::GLRender",
00156         "can't open file \"%s\".",fileName.getValue().getString());
00157     } else {
00158       int coln;
00159       Uchar* rs;
00160       Uchar* gs;
00161       Uchar* bs;
00162       Uchar* data;
00163       getImagePixels(w,h,image,coln,rs,gs,bs,data);
00164       
00165       SbGIF::putBytesInStream(file,data,w,h,coln,rs,gs,bs);
00166       
00167       delete [] data;
00168 
00169       if(rs) free(rs);
00170       if(gs) free(gs);
00171       if(bs) free(bs);
00172 
00173       fclose(file);
00174 
00175       fStatus = TRUE;
00176     }
00177   } else {
00178 */
00179 
00180     SbPainterPS painterPS;
00181     painterPS.openFileForWriting(fileName.getValue().getString());
00182     if(!painterPS.getStream()) {
00183       SoDebugError::postInfo("SoImageWriter::GLRender",
00184         "can't open file \"%s\".",fileName.getValue().getString());
00185     } else {
00186       painterPS.setWindowSize(w,h);
00187       //painterPS.setBitsPerPixel(8);
00188       painterPS.setBitsPerPixel(4);
00189       painterPS.beginTraversal();
00190       painterPS.clearColorBuffer(1.,1.,1.);
00191 
00192       sWidth = w;
00193       sHeight = h;
00194       sImage = image;
00195       painterPS.putImageInStream((unsigned int)w,(unsigned int)h,getRGB);
00196       
00197       painterPS.endTraversal();
00198       
00199       painterPS.closeStream();
00200       
00201       fStatus = TRUE;
00202     }
00203   //}
00204   delete [] image;
00205 
00206 }
00207 /*
00209 void getImagePixels (
00210  int aWidth
00211 ,int aHeight
00212 ,float* aImage
00213 ,int& aColorn
00214 ,Uchar*& aReds
00215 ,Uchar*& aGreens
00216 ,Uchar*& aBlues
00217 ,Uchar*& aData
00218 )
00221 {
00222   aColorn = 0;
00223   aReds = 0;
00224   aGreens = 0;
00225   aBlues = 0;
00226   aData = 0;
00227   if( (aWidth * aHeight) <=0) return;
00228   int size = 256;
00229   Uchar* rs = (Uchar*)malloc(size * sizeof(Uchar));
00230   Uchar* gs = (Uchar*)malloc(size * sizeof(Uchar));
00231   Uchar* bs = (Uchar*)malloc(size * sizeof(Uchar));
00232   Uchar* data = new Uchar[aWidth * aHeight];
00233   if( !rs || !gs || !bs || !data ) {
00234     if(rs) free(rs);
00235     if(gs) free(gs);
00236     if(bs) free(bs);
00237     delete [] data;
00238     return;
00239   }
00240   int pixeln = 0;
00241   int row,col;
00242   Uchar red,green,blue;
00243   Uchar ored = 0,ogreen = 0,oblue = 0;
00244   float* pimag = aImage;
00245   Uchar* pdata = 0;
00246   Uchar index = 0;
00247   int status = 0;
00248   for(row=0;row<aHeight;row++) {
00249     pdata = data + (aHeight - 1 - row) * aWidth;
00250     for(col=0;col<aWidth;col++){ 
00251       red   = (Uchar)(255 * (*pimag));pimag++;
00252       green = (Uchar)(255 * (*pimag));pimag++;
00253       blue  = (Uchar)(255 * (*pimag));pimag++;
00254       //printf("debug : %d %d : %d %d %d\n",row,col,red,green,blue);
00255       if( (pixeln==0) || (red!=ored) || (green!=ogreen) || (blue!=oblue) ){
00256         // Search exact color :
00257         int found = 0;
00258         for(int count=0;count<pixeln;count++){
00259           if( (red==rs[count]) && (green==gs[count]) && (blue==bs[count]) ){
00260             found = 1;
00261             index = count;
00262             break;
00263           }
00264         }
00265         if(found==0){
00266           if(pixeln>=256) {
00267             // We can't store more than 256 on an Uchar.
00268             // Search closest color :
00269             int dr,dg,db;
00270             int PRECISION = 20;
00271             int closest = 0;
00272             for(int count=0;count<pixeln;count++){
00273               dr = red   - rs[count];dr = dr<0 ? -dr : dr;
00274               dg = green - gs[count];dg = dg<0 ? -dg : dg;
00275               db = blue  - bs[count];db = db<0 ? -db : db;
00276               if( (dr<=PRECISION) && (dg<=PRECISION) && (db<=PRECISION) ){
00277                 closest = 1;
00278                 index = count;
00279                 break;
00280               }
00281             }
00282             if(closest==0) {
00283               index = 0;
00284               status  = 1;
00285             }
00286           } else {
00287             if(pixeln>=size){
00288               size += 256;
00289               rs = (Uchar*)realloc(rs,size * sizeof(Uchar));
00290               gs = (Uchar*)realloc(gs,size * sizeof(Uchar));
00291               bs = (Uchar*)realloc(bs,size * sizeof(Uchar));
00292               if( !rs || !gs || !bs ) {
00293                 if(rs) free(rs);
00294                 if(gs) free(gs);
00295                 if(bs) free(bs);
00296                 delete [] data;
00297                 return;
00298               } 
00299             } 
00300             //printf("debug : SoImageWriter pixeln %d : %d %d %d\n",
00301             //   pixeln,red,green,blue);
00302             rs[pixeln] = red;
00303             gs[pixeln] = green;
00304             bs[pixeln] = blue;
00305             index = pixeln;
00306             pixeln++;
00307           }
00308         }
00309       }
00310       *pdata = index;
00311       pdata++;
00312       ored = red;
00313       ogreen = green;
00314       oblue = blue;
00315     }
00316   }
00317   if(status==1) 
00318     printf("SoImageWriter : more than 256 colors in picture ; some colors approximated.\n");
00319   aColorn = pixeln;
00320   aReds = rs;
00321   aGreens = gs;
00322   aBlues = bs;
00323   aData = data;
00324 }
00325 */
00327 int getRGB(
00328  unsigned int aX
00329 ,unsigned int aY
00330 ,double& aRed
00331 ,double& aGreen
00332 ,double& aBlue
00333 )
00335 // OpenGL image is from down to up.
00336 // PS image is up to down.
00338 {
00339   float* pimag = sImage + 3 * (sWidth * (sHeight - 1 - aY) + aX);
00340   aRed   = *pimag;pimag++;
00341   aGreen = *pimag;pimag++;
00342   aBlue  = *pimag;pimag++;
00343   return 1;
00344 }
00345 
00346 #endif

Generated on Mon May 27 17:50:34 2013 for Geant4 by  doxygen 1.4.7