Geant4 Cross Reference |
1 // 1 // 2 // ******************************************* 2 // ******************************************************************** 3 // * License and Disclaimer 3 // * License and Disclaimer * 4 // * 4 // * * 5 // * The Geant4 software is copyright of th 5 // * The Geant4 software is copyright of the Copyright Holders of * 6 // * the Geant4 Collaboration. It is provided 6 // * the Geant4 Collaboration. It is provided under the terms and * 7 // * conditions of the Geant4 Software License 7 // * conditions of the Geant4 Software License, included in the file * 8 // * LICENSE and available at http://cern.ch/ 8 // * LICENSE and available at http://cern.ch/geant4/license . These * 9 // * include a list of copyright holders. 9 // * include a list of copyright holders. * 10 // * 10 // * * 11 // * Neither the authors of this software syst 11 // * Neither the authors of this software system, nor their employing * 12 // * institutes,nor the agencies providing fin 12 // * institutes,nor the agencies providing financial support for this * 13 // * work make any representation or warran 13 // * work make any representation or warranty, express or implied, * 14 // * regarding this software system or assum 14 // * regarding this software system or assume any liability for its * 15 // * use. Please see the license in the file 15 // * use. Please see the license in the file LICENSE and URL above * 16 // * for the full disclaimer and the limitatio 16 // * for the full disclaimer and the limitation of liability. * 17 // * 17 // * * 18 // * This code implementation is the result 18 // * This code implementation is the result of the scientific and * 19 // * technical work of the GEANT4 collaboratio 19 // * technical work of the GEANT4 collaboration. * 20 // * By using, copying, modifying or distri 20 // * By using, copying, modifying or distributing the software (or * 21 // * any work based on the software) you ag 21 // * any work based on the software) you agree to acknowledge its * 22 // * use in resulting scientific publicati 22 // * use in resulting scientific publications, and indicate your * 23 // * acceptance of all terms of the Geant4 Sof 23 // * acceptance of all terms of the Geant4 Software license. * 24 // ******************************************* 24 // ******************************************************************** 25 // 25 // 26 26 27 /*----------------------------HEPVis---------- 27 /*----------------------------HEPVis----------------------------------------*/ 28 /* 28 /* */ 29 /* Node: SoImageWriter 29 /* Node: SoImageWriter */ 30 /* Author: Guy Barrand 30 /* Author: Guy Barrand */ 31 /* 31 /* */ 32 /*-------------------------------------------- 32 /*--------------------------------------------------------------------------*/ 33 33 34 // this : 34 // this : 35 #include <HEPVis/nodes/SoImageWriter.h> 35 #include <HEPVis/nodes/SoImageWriter.h> 36 36 37 #include <Inventor/errors/SoDebugError.h> 37 #include <Inventor/errors/SoDebugError.h> 38 #include <Inventor/elements/SoViewportRegionEl 38 #include <Inventor/elements/SoViewportRegionElement.h> 39 #include <Inventor/actions/SoGLRenderAction.h> 39 #include <Inventor/actions/SoGLRenderAction.h> 40 40 41 #include <HEPVis/SbGL.h> 41 #include <HEPVis/SbGL.h> 42 #include <HEPVis/SbPainterPS.h> 42 #include <HEPVis/SbPainterPS.h> 43 //#include <HEPVis/SbGIF.h> 43 //#include <HEPVis/SbGIF.h> 44 44 45 #include <stdlib.h> 45 #include <stdlib.h> 46 46 47 typedef struct { 47 typedef struct { 48 unsigned char red; 48 unsigned char red; 49 unsigned char green; 49 unsigned char green; 50 unsigned char blue; 50 unsigned char blue; 51 } Pixel; 51 } Pixel; 52 typedef unsigned char Uchar; 52 typedef unsigned char Uchar; 53 53 54 //static void getImagePixels(int,int,float*,in 54 //static void getImagePixels(int,int,float*,int&, 55 // Uchar*&,Uchar*&,Uch 55 // Uchar*&,Uchar*&,Uchar*&,Uchar*&); 56 56 57 static int sWidth = 0; 57 static int sWidth = 0; 58 static int sHeight = 0; 58 static int sHeight = 0; 59 static float* sImage = 0; 59 static float* sImage = 0; 60 static int getRGB(unsigned int,unsigned int,do 60 static int getRGB(unsigned int,unsigned int,double&,double&,double&); 61 61 62 SO_NODE_SOURCE(SoImageWriter) 62 SO_NODE_SOURCE(SoImageWriter) 63 ////////////////////////////////////////////// 63 ////////////////////////////////////////////////////////////////////////////// 64 void SoImageWriter::initClass ( 64 void SoImageWriter::initClass ( 65 ) 65 ) 66 ////////////////////////////////////////////// 66 ////////////////////////////////////////////////////////////////////////////// 67 //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! 67 //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!// 68 { 68 { 69 static bool first = true; 69 static bool first = true; 70 if (first) { 70 if (first) { 71 first = false; 71 first = false; 72 SO_NODE_INIT_CLASS(SoImageWriter,SoNode,"N 72 SO_NODE_INIT_CLASS(SoImageWriter,SoNode,"Node"); 73 } 73 } 74 } 74 } 75 ////////////////////////////////////////////// 75 ////////////////////////////////////////////////////////////////////////////// 76 SoImageWriter::SoImageWriter( 76 SoImageWriter::SoImageWriter( 77 ) 77 ) 78 :fEnabled(FALSE) 78 :fEnabled(FALSE) 79 ,fStatus(FALSE) 79 ,fStatus(FALSE) 80 ////////////////////////////////////////////// 80 ////////////////////////////////////////////////////////////////////////////// 81 //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! 81 //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!// 82 { 82 { 83 SO_NODE_CONSTRUCTOR(SoImageWriter); 83 SO_NODE_CONSTRUCTOR(SoImageWriter); 84 //SO_NODE_ADD_FIELD(format,(POST_SCRIPT)); 84 //SO_NODE_ADD_FIELD(format,(POST_SCRIPT)); 85 SO_NODE_ADD_FIELD(fileName,("out.ps")); 85 SO_NODE_ADD_FIELD(fileName,("out.ps")); 86 86 87 //SO_NODE_DEFINE_ENUM_VALUE(Format,POST_SCRI 87 //SO_NODE_DEFINE_ENUM_VALUE(Format,POST_SCRIPT); 88 //SO_NODE_DEFINE_ENUM_VALUE(Format,GIF); 88 //SO_NODE_DEFINE_ENUM_VALUE(Format,GIF); 89 89 90 //SO_NODE_SET_SF_ENUM_TYPE(format,Format); 90 //SO_NODE_SET_SF_ENUM_TYPE(format,Format); 91 } 91 } 92 ////////////////////////////////////////////// 92 ////////////////////////////////////////////////////////////////////////////// 93 SoImageWriter::~SoImageWriter ( 93 SoImageWriter::~SoImageWriter ( 94 ) 94 ) 95 ////////////////////////////////////////////// 95 ////////////////////////////////////////////////////////////////////////////// 96 //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! 96 //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!// 97 { 97 { 98 } 98 } 99 ////////////////////////////////////////////// 99 ////////////////////////////////////////////////////////////////////////////// 100 void SoImageWriter::enable( 100 void SoImageWriter::enable( 101 ) 101 ) 102 ////////////////////////////////////////////// 102 ////////////////////////////////////////////////////////////////////////////// 103 //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! 103 //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!// 104 { 104 { 105 fEnabled = TRUE; 105 fEnabled = TRUE; 106 } 106 } 107 ////////////////////////////////////////////// 107 ////////////////////////////////////////////////////////////////////////////// 108 void SoImageWriter::disable( 108 void SoImageWriter::disable( 109 ) 109 ) 110 ////////////////////////////////////////////// 110 ////////////////////////////////////////////////////////////////////////////// 111 //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! 111 //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!// 112 { 112 { 113 fEnabled = FALSE; 113 fEnabled = FALSE; 114 } 114 } 115 ////////////////////////////////////////////// 115 ////////////////////////////////////////////////////////////////////////////// 116 SbBool SoImageWriter::getStatus( 116 SbBool SoImageWriter::getStatus( 117 ) const 117 ) const 118 ////////////////////////////////////////////// 118 ////////////////////////////////////////////////////////////////////////////// 119 //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! 119 //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!// 120 { 120 { 121 return fStatus; 121 return fStatus; 122 } 122 } 123 ////////////////////////////////////////////// 123 ////////////////////////////////////////////////////////////////////////////// 124 void SoImageWriter::GLRender( 124 void SoImageWriter::GLRender( 125 SoGLRenderAction* aAction 125 SoGLRenderAction* aAction 126 ) 126 ) 127 ////////////////////////////////////////////// 127 ////////////////////////////////////////////////////////////////////////////// 128 //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! 128 //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!// 129 { 129 { 130 fStatus = FALSE; 130 fStatus = FALSE; 131 //printf("debug : SoImageWriter::GLRender : 131 //printf("debug : SoImageWriter::GLRender : enabled : %d\n",fEnabled); 132 if(!fEnabled) return; 132 if(!fEnabled) return; 133 SbViewportRegion vpr = SoViewportRegionEleme 133 SbViewportRegion vpr = SoViewportRegionElement::get(aAction->getState()); 134 const SbVec2s& win = vpr.getWindowSize(); 134 const SbVec2s& win = vpr.getWindowSize(); 135 int w = win[0]; 135 int w = win[0]; 136 int h = win[1]; 136 int h = win[1]; 137 if((w*h)<=0) { 137 if((w*h)<=0) { 138 SoDebugError::postInfo("SoImageWriter::GLR 138 SoDebugError::postInfo("SoImageWriter::GLRender","null area window !"); 139 return; 139 return; 140 } 140 } 141 141 142 int x = 0; 142 int x = 0; 143 int y = 0; 143 int y = 0; 144 int s = 3 * w * h; 144 int s = 3 * w * h; 145 float* image = new float[s]; 145 float* image = new float[s]; 146 if(!image) return; 146 if(!image) return; 147 147 148 //printf("debug : SoImageWriter::GLRender : 148 //printf("debug : SoImageWriter::GLRender : %d %d %d %d\n",x,y,w,h); 149 149 150 //glReadPixels(x,y,w,h,GL_RGB,GL_UNSIGNED_BY 150 //glReadPixels(x,y,w,h,GL_RGB,GL_UNSIGNED_BYTE,image); Don't work ! 151 glReadPixels(x,y,w,h,GL_RGB,GL_FLOAT,image); 151 glReadPixels(x,y,w,h,GL_RGB,GL_FLOAT,image); 152 152 153 //Format fm = (Format)format.getValue(); 153 //Format fm = (Format)format.getValue(); 154 //if(fm==GIF) { 154 //if(fm==GIF) { 155 /* 155 /* 156 FILE* file = fopen(fileName.getValue().get 156 FILE* file = fopen(fileName.getValue().getString(),"wb"); 157 if(!file) { 157 if(!file) { 158 SoDebugError::postInfo("SoImageWriter::G 158 SoDebugError::postInfo("SoImageWriter::GLRender", 159 "can't open file \"%s\".",fileName.get 159 "can't open file \"%s\".",fileName.getValue().getString()); 160 } else { 160 } else { 161 int coln; 161 int coln; 162 Uchar* rs; 162 Uchar* rs; 163 Uchar* gs; 163 Uchar* gs; 164 Uchar* bs; 164 Uchar* bs; 165 Uchar* data; 165 Uchar* data; 166 getImagePixels(w,h,image,coln,rs,gs,bs,d 166 getImagePixels(w,h,image,coln,rs,gs,bs,data); 167 167 168 SbGIF::putBytesInStream(file,data,w,h,co 168 SbGIF::putBytesInStream(file,data,w,h,coln,rs,gs,bs); 169 169 170 delete [] data; 170 delete [] data; 171 171 172 if(rs) free(rs); 172 if(rs) free(rs); 173 if(gs) free(gs); 173 if(gs) free(gs); 174 if(bs) free(bs); 174 if(bs) free(bs); 175 175 176 fclose(file); 176 fclose(file); 177 177 178 fStatus = TRUE; 178 fStatus = TRUE; 179 } 179 } 180 } else { 180 } else { 181 */ 181 */ 182 182 183 SbPainterPS painterPS; 183 SbPainterPS painterPS; 184 painterPS.openFileForWriting(fileName.getV 184 painterPS.openFileForWriting(fileName.getValue().getString()); 185 if(!painterPS.getStream()) { 185 if(!painterPS.getStream()) { 186 SoDebugError::postInfo("SoImageWriter::G 186 SoDebugError::postInfo("SoImageWriter::GLRender", 187 "can't open file \"%s\".",fileName.get 187 "can't open file \"%s\".",fileName.getValue().getString()); 188 } else { 188 } else { 189 painterPS.setWindowSize(w,h); 189 painterPS.setWindowSize(w,h); 190 //painterPS.setBitsPerPixel(8); 190 //painterPS.setBitsPerPixel(8); 191 painterPS.setBitsPerPixel(4); 191 painterPS.setBitsPerPixel(4); 192 painterPS.beginTraversal(); 192 painterPS.beginTraversal(); 193 painterPS.clearColorBuffer(1.,1.,1.); 193 painterPS.clearColorBuffer(1.,1.,1.); 194 194 195 sWidth = w; 195 sWidth = w; 196 sHeight = h; 196 sHeight = h; 197 sImage = image; 197 sImage = image; 198 painterPS.putImageInStream((unsigned int 198 painterPS.putImageInStream((unsigned int)w,(unsigned int)h,getRGB); 199 199 200 painterPS.endTraversal(); 200 painterPS.endTraversal(); 201 201 202 painterPS.closeStream(); 202 painterPS.closeStream(); 203 203 204 fStatus = TRUE; 204 fStatus = TRUE; 205 } 205 } 206 //} 206 //} 207 delete [] image; 207 delete [] image; 208 208 209 } 209 } 210 /* 210 /* 211 ////////////////////////////////////////////// 211 ////////////////////////////////////////////////////////////////////////////// 212 void getImagePixels ( 212 void getImagePixels ( 213 int aWidth 213 int aWidth 214 ,int aHeight 214 ,int aHeight 215 ,float* aImage 215 ,float* aImage 216 ,int& aColorn 216 ,int& aColorn 217 ,Uchar*& aReds 217 ,Uchar*& aReds 218 ,Uchar*& aGreens 218 ,Uchar*& aGreens 219 ,Uchar*& aBlues 219 ,Uchar*& aBlues 220 ,Uchar*& aData 220 ,Uchar*& aData 221 ) 221 ) 222 ////////////////////////////////////////////// 222 ////////////////////////////////////////////////////////////////////////////// 223 //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! 223 //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!// 224 { 224 { 225 aColorn = 0; 225 aColorn = 0; 226 aReds = 0; 226 aReds = 0; 227 aGreens = 0; 227 aGreens = 0; 228 aBlues = 0; 228 aBlues = 0; 229 aData = 0; 229 aData = 0; 230 if( (aWidth * aHeight) <=0) return; 230 if( (aWidth * aHeight) <=0) return; 231 int size = 256; 231 int size = 256; 232 Uchar* rs = (Uchar*)malloc(size * sizeof(Uch 232 Uchar* rs = (Uchar*)malloc(size * sizeof(Uchar)); 233 Uchar* gs = (Uchar*)malloc(size * sizeof(Uch 233 Uchar* gs = (Uchar*)malloc(size * sizeof(Uchar)); 234 Uchar* bs = (Uchar*)malloc(size * sizeof(Uch 234 Uchar* bs = (Uchar*)malloc(size * sizeof(Uchar)); 235 Uchar* data = new Uchar[aWidth * aHeight]; 235 Uchar* data = new Uchar[aWidth * aHeight]; 236 if( !rs || !gs || !bs || !data ) { 236 if( !rs || !gs || !bs || !data ) { 237 if(rs) free(rs); 237 if(rs) free(rs); 238 if(gs) free(gs); 238 if(gs) free(gs); 239 if(bs) free(bs); 239 if(bs) free(bs); 240 delete [] data; 240 delete [] data; 241 return; 241 return; 242 } 242 } 243 int pixeln = 0; 243 int pixeln = 0; 244 int row,col; 244 int row,col; 245 Uchar red,green,blue; 245 Uchar red,green,blue; 246 Uchar ored = 0,ogreen = 0,oblue = 0; 246 Uchar ored = 0,ogreen = 0,oblue = 0; 247 float* pimag = aImage; 247 float* pimag = aImage; 248 Uchar* pdata = 0; 248 Uchar* pdata = 0; 249 Uchar index = 0; 249 Uchar index = 0; 250 int status = 0; 250 int status = 0; 251 for(row=0;row<aHeight;row++) { 251 for(row=0;row<aHeight;row++) { 252 pdata = data + (aHeight - 1 - row) * aWidt 252 pdata = data + (aHeight - 1 - row) * aWidth; 253 for(col=0;col<aWidth;col++){ 253 for(col=0;col<aWidth;col++){ 254 red = (Uchar)(255 * (*pimag));pimag++; 254 red = (Uchar)(255 * (*pimag));pimag++; 255 green = (Uchar)(255 * (*pimag));pimag++; 255 green = (Uchar)(255 * (*pimag));pimag++; 256 blue = (Uchar)(255 * (*pimag));pimag++; 256 blue = (Uchar)(255 * (*pimag));pimag++; 257 //printf("debug : %d %d : %d %d %d\n",ro 257 //printf("debug : %d %d : %d %d %d\n",row,col,red,green,blue); 258 if( (pixeln==0) || (red!=ored) || (green 258 if( (pixeln==0) || (red!=ored) || (green!=ogreen) || (blue!=oblue) ){ 259 // Search exact color : 259 // Search exact color : 260 int found = 0; 260 int found = 0; 261 for(int count=0;count<pixeln;count++){ 261 for(int count=0;count<pixeln;count++){ 262 if( (red==rs[count]) && (green==gs[c 262 if( (red==rs[count]) && (green==gs[count]) && (blue==bs[count]) ){ 263 found = 1; 263 found = 1; 264 index = count; 264 index = count; 265 break; 265 break; 266 } 266 } 267 } 267 } 268 if(found==0){ 268 if(found==0){ 269 if(pixeln>=256) { 269 if(pixeln>=256) { 270 // We can't store more than 256 on 270 // We can't store more than 256 on an Uchar. 271 // Search closest color : 271 // Search closest color : 272 int dr,dg,db; 272 int dr,dg,db; 273 int PRECISION = 20; 273 int PRECISION = 20; 274 int closest = 0; 274 int closest = 0; 275 for(int count=0;count<pixeln;count 275 for(int count=0;count<pixeln;count++){ 276 dr = red - rs[count];dr = dr<0 276 dr = red - rs[count];dr = dr<0 ? -dr : dr; 277 dg = green - gs[count];dg = dg<0 277 dg = green - gs[count];dg = dg<0 ? -dg : dg; 278 db = blue - bs[count];db = db<0 278 db = blue - bs[count];db = db<0 ? -db : db; 279 if( (dr<=PRECISION) && (dg<=PREC 279 if( (dr<=PRECISION) && (dg<=PRECISION) && (db<=PRECISION) ){ 280 closest = 1; 280 closest = 1; 281 index = count; 281 index = count; 282 break; 282 break; 283 } 283 } 284 } 284 } 285 if(closest==0) { 285 if(closest==0) { 286 index = 0; 286 index = 0; 287 status = 1; 287 status = 1; 288 } 288 } 289 } else { 289 } else { 290 if(pixeln>=size){ 290 if(pixeln>=size){ 291 size += 256; 291 size += 256; 292 rs = (Uchar*)realloc(rs,size * s 292 rs = (Uchar*)realloc(rs,size * sizeof(Uchar)); 293 gs = (Uchar*)realloc(gs,size * s 293 gs = (Uchar*)realloc(gs,size * sizeof(Uchar)); 294 bs = (Uchar*)realloc(bs,size * s 294 bs = (Uchar*)realloc(bs,size * sizeof(Uchar)); 295 if( !rs || !gs || !bs ) { 295 if( !rs || !gs || !bs ) { 296 if(rs) free(rs); 296 if(rs) free(rs); 297 if(gs) free(gs); 297 if(gs) free(gs); 298 if(bs) free(bs); 298 if(bs) free(bs); 299 delete [] data; 299 delete [] data; 300 return; 300 return; 301 } 301 } 302 } 302 } 303 //printf("debug : SoImageWriter pi 303 //printf("debug : SoImageWriter pixeln %d : %d %d %d\n", 304 // pixeln,red,green,blue); 304 // pixeln,red,green,blue); 305 rs[pixeln] = red; 305 rs[pixeln] = red; 306 gs[pixeln] = green; 306 gs[pixeln] = green; 307 bs[pixeln] = blue; 307 bs[pixeln] = blue; 308 index = pixeln; 308 index = pixeln; 309 pixeln++; 309 pixeln++; 310 } 310 } 311 } 311 } 312 } 312 } 313 *pdata = index; 313 *pdata = index; 314 pdata++; 314 pdata++; 315 ored = red; 315 ored = red; 316 ogreen = green; 316 ogreen = green; 317 oblue = blue; 317 oblue = blue; 318 } 318 } 319 } 319 } 320 if(status==1) 320 if(status==1) 321 printf("SoImageWriter : more than 256 colo 321 printf("SoImageWriter : more than 256 colors in picture ; some colors approximated.\n"); 322 aColorn = pixeln; 322 aColorn = pixeln; 323 aReds = rs; 323 aReds = rs; 324 aGreens = gs; 324 aGreens = gs; 325 aBlues = bs; 325 aBlues = bs; 326 aData = data; 326 aData = data; 327 } 327 } 328 */ 328 */ 329 ////////////////////////////////////////////// 329 ////////////////////////////////////////////////////////////////////////////// 330 int getRGB( 330 int getRGB( 331 unsigned int aX 331 unsigned int aX 332 ,unsigned int aY 332 ,unsigned int aY 333 ,double& aRed 333 ,double& aRed 334 ,double& aGreen 334 ,double& aGreen 335 ,double& aBlue 335 ,double& aBlue 336 ) 336 ) 337 ////////////////////////////////////////////// 337 ////////////////////////////////////////////////////////////////////////////// 338 // OpenGL image is from down to up. 338 // OpenGL image is from down to up. 339 // PS image is up to down. 339 // PS image is up to down. 340 //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! 340 //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!// 341 { 341 { 342 float* pimag = sImage + 3 * (sWidth * (sHeig 342 float* pimag = sImage + 3 * (sWidth * (sHeight - 1 - aY) + aX); 343 aRed = *pimag;pimag++; 343 aRed = *pimag;pimag++; 344 aGreen = *pimag;pimag++; 344 aGreen = *pimag;pimag++; 345 aBlue = *pimag;pimag++; 345 aBlue = *pimag;pimag++; 346 return 1; 346 return 1; 347 } 347 } 348 348