00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #include <util/gliftUtil.h>
00021 #include <texture/subTex.h>
00022 #include <texture/texNd.h>
00023 #include <drawable/planarQuad.h>
00024 #include <drawable/shadedPrim.h>
00025 #include <texCoordGen/winTexGen2D.h>
00026
00027 #ifdef GLIFT_NRRD
00028 #include <nrrd.h>
00029 #endif
00030 #include <string>
00031 #include <vector>
00032
00033 using namespace std;
00034 using namespace gutz;
00035
00036 using namespace glift;
00037
00038
00039
00040
00041 const GLenum g_texUnitName[NUM_TEX_UNIT_NAMES] =
00042 {
00043 GL_TEXTURE0,
00044 GL_TEXTURE1,
00045 GL_TEXTURE2,
00046 GL_TEXTURE3,
00047 GL_TEXTURE4,
00048 GL_TEXTURE5,
00049 GL_TEXTURE6,
00050 GL_TEXTURE7,
00051 GL_TEXTURE8,
00052 GL_TEXTURE9,
00053 GL_TEXTURE10,
00054 GL_TEXTURE11,
00055 GL_TEXTURE12,
00056 GL_TEXTURE13,
00057 GL_TEXTURE14,
00058 GL_TEXTURE15,
00059 GL_TEXTURE16,
00060 GL_TEXTURE17,
00061 GL_TEXTURE18,
00062 GL_TEXTURE19,
00063 GL_TEXTURE20,
00064 GL_TEXTURE21,
00065 GL_TEXTURE22,
00066 GL_TEXTURE23,
00067 GL_TEXTURE24,
00068 GL_TEXTURE25,
00069 GL_TEXTURE26,
00070 GL_TEXTURE27,
00071 GL_TEXTURE28,
00072 GL_TEXTURE29,
00073 GL_TEXTURE30,
00074 GL_TEXTURE31,
00075 };
00076
00077
00078
00079
00080
00081 void drawPixels( const arrayw3ub& data, SingleTex* tex, GLenum drawBuffer )
00082 {
00083 drawSubPixels( vec2i(0), vec2i(0), vec2i(data.dim(1), data.dim(0)), data, tex, drawBuffer );
00084 }
00085
00086
00087
00088
00089 void drawSubPixels( const vec2i& dataOrig, const vec2i& texOrig, const vec2i& dimen,
00090 const arrayw3ub& data, SingleTex* tex, GLenum drawBuffer )
00091 {
00092
00093 int numChannels = data.dim(2);
00094 GLenum glType;
00095 if( numChannels == 1 ) { glType = GL_LUMINANCE; }
00096 else if( numChannels == 3 ) { glType = GL_RGB; }
00097 else if( numChannels == 4 ) { glType = GL_RGBA; }
00098 else {
00099 cerr << "glift::drawSubPixels(...) Error:\n\tCan only draw data with 1, 3, or 4 color channels.\n";
00100 exit(1);
00101 }
00102
00103
00104 ubyte* dataPtr = (uchar*)data.data();
00105 bool nukeData = false;
00106
00107 #ifdef GLIFT_NRRD
00108 if( dataOrig != 0 ) {
00109 vec3i minV( 0, dataOrig.x, dataOrig.y);
00110 vec3i maxV( numChannels - 1, dimen.x + dataOrig.x - 1, dimen.y + dataOrig.y - 1 );
00111
00112 int e = 0;
00113 Nrrd* nIn = nrrdNew();
00114 Nrrd* nOut = nrrdNew();
00115 nerr( nrrdWrap(nIn, dataPtr, nrrdTypeUChar, 3, data.dim(2), data.dim(1), data.dim(0)), e );
00116 nerr( nrrdCrop(nOut, nIn, minV.v(), maxV.v()), e );
00117
00118 dataPtr = (ubyte*)nOut->data;
00119 nrrdNix(nIn);
00120 nrrdNix(nOut);
00121 nukeData = true;
00122
00123 if( e ) {
00124 cerr << "drawSubPixels(...) Error\n"
00125 << biffGetDone(NRRD) << endl;
00126 exit(1);
00127 }
00128 }
00129 #else
00130 if( dataOrig != 0 ) {
00131 cerr << "drawSubPixels(...) Error:\n\t"
00132 << "'dataOrig' != 0.\n"
00133 << "\tGlift must be compiled with GLIFT_NRRD defined for this to work.\n";
00134 exit(1);
00135 }
00136 #endif
00137
00138
00139 PBuffGlift* pbuff = tex->pbuff();
00140 if( pbuff ) {
00141 pbuff->enable();
00142 }
00143
00144
00145
00146
00147
00148
00149
00150
00151 int saveDrawBuff = 0;
00152 glGetIntegerv( GL_DRAW_BUFFER, &saveDrawBuff );
00153 glDrawBuffer( drawBuffer );
00154
00155
00156 if( SubTex* vtex = dynamic_cast<SubTex*>(tex) ) {
00157 vec2i origin = vtex->origin() + texOrig;
00158 setColorMask( vtex->channel() );
00159 glRasterPos2i( origin.x, origin.y );
00160 glDrawPixels( dimen.x, dimen.y, glType, GL_UNSIGNED_BYTE, dataPtr );
00161
00162 glRasterPos2i(0,0);
00163 setColorMask( GL_RGBA );
00164 }
00165 else {
00166 glRasterPos2i(texOrig.x, texOrig.y);
00167 glDrawPixels( dimen.x, dimen.y, glType, GL_UNSIGNED_BYTE, dataPtr );
00168 glRasterPos2i(0,0);
00169 }
00170
00171
00172 glDrawBuffer( saveDrawBuff );
00173 if( pbuff) {
00174
00175 }
00176 else {
00177 if( Tex2D* tex2D = dynamic_cast<Tex2D*>(tex) ) {
00178 tex2D->copyToTex2D();
00179 }
00180 }
00181
00182 if( nukeData ) {free(dataPtr); }
00183 }
00184
00185
00186
00187
00188
00189
00190
00191
00192
00193
00194 void drawPixels( const arrayw3f& data, SingleTex* tex )
00195 {
00196 vec2i size( data.dim(1), data.dim(0) );
00197
00198
00199 int numChannels = data.dim(2);
00200 GLenum glType;
00201 if( numChannels == 1 ) { glType = GL_LUMINANCE; }
00202 else if( numChannels == 3 ) { glType = GL_RGB; }
00203 else if( numChannels == 4 ) { glType = GL_RGBA; }
00204 else {
00205 cerr << "glift::drawSubPixels(...) Error:\n\tCan only draw data with 1, 3, or 4 color channels.\n";
00206 exit(1);
00207 }
00208
00209
00210 PBuffGlift* pbuff = tex->pbuff();
00211 if( pbuff ) {
00212 pbuff->enable();
00213 }
00214
00215
00216 int saveDrawBuff = 0;
00217 glGetIntegerv( GL_DRAW_BUFFER, &saveDrawBuff );
00218
00219
00220 if( SubPBuff* subPB = dynamic_cast<SubPBuff*>(tex->pbuff()) ) {
00221 glDrawBuffer( subPB->glSurface() );
00222 }
00223
00224
00225 glRasterPos2i(0,0);
00226 glDrawPixels( size.x, size.y, glType, GL_FLOAT, (float*)data.data() );
00227 glRasterPos2i(0,0);
00228
00229
00230 glDrawBuffer( saveDrawBuff );
00231 }
00232
00233 void drawSingleTexQuad( SingleTex* tex, bool drawToPbuff )
00234 {
00235 drawSingleTexQuad(tex, tex->dimen(), drawToPbuff );
00236 }
00237
00238
00239
00240
00241 void drawSingleTexQuad( SingleTex* tex, const vec2i& dimen, bool drawToPbuff )
00242 {
00243
00244 if( tex == NULL ) {
00245 return;
00246 }
00247
00248
00249 PlanarQuad* quadP = NULL;
00250
00251
00252 if( dynamic_cast<TexRect*>(tex) ) {
00253
00254 WinTexGen2D* texGen = new WinTexGen2D();
00255 quadP = new PlanarQuad( vec2f(), vec2f((float)dimen.x, (float)dimen.y), 0.0f, true,
00256 false, texGen );
00257 delete texGen;
00258 }
00259 else {
00260 quadP = new PlanarQuad( vec2f(0.0f), vec2f( (float)dimen.x, (float)dimen.y), 0.0f, true );
00261 }
00262 Shader shader = Shader( tex );
00263 ShadedPrim shadedQuad( quadP, &shader );
00264
00265 PBuffGlift* pbuff = tex->pbuff();
00266 if( drawToPbuff ) {
00267 if( pbuff ) {
00268 pbuff->enable(true);
00269 }
00270
00271 tex->tryToBindPbuff(false);
00272 }
00273
00274
00275
00276
00277
00278
00279
00280
00281
00282 if( SubTex* subtex = dynamic_cast<SubTex*>(tex) ) {
00283 if( subtex->channel() != GL_RGBA ) {
00284 glClear(GL_COLOR_BUFFER_BIT);
00285 setColorMask( subtex->channel() );
00286 }
00287 }
00288
00289 shadedQuad.draw();
00290 setColorMask( GL_RGBA );
00291
00292
00293
00294
00295
00296 if( drawToPbuff ) {
00297 tex->tryToBindPbuff(true);
00298
00299 if( pbuff ) {
00300 pbuff->disable();
00301 }
00302 }
00303 }
00304
00305
00306
00307 void drawColoredTile( const vec2i& origin, const vec2i& dimen, const vec2i& fullQuadDim,
00308 const vec3f& color, SingleTex* tex )
00309 {
00310 assert(tex);
00311 PBuffGlift* pbuff = tex->pbuff();
00312
00313 vec2i lowerLeft = origin;
00314 vec2i upperRight = origin + dimen;
00315
00316 vec2f lowerLeftF( 0.0f, 0.0f );
00317 vec2f upperRightF( (float)fullQuadDim.x, (float)fullQuadDim.y);
00318
00319 static PlanarQuad quad( lowerLeftF, upperRightF, 0.0f );
00320
00321 if( pbuff ) {
00322 pbuff->enable();
00323 }
00324 vec4i oldView;
00325 glGetIntegerv(GL_VIEWPORT, oldView.v());
00326
00327 glColor3f(color.x, color.y, color.z);
00328 glViewport(lowerLeft.x, lowerLeft.y, dimen.x, dimen.y);
00329 quad.draw();
00330
00331
00332 glViewport(oldView[0], oldView[1], oldView[2], oldView[3]);
00333 if( pbuff ) {
00334
00335 }
00336 else {
00337 if( Tex2D* tex2D = dynamic_cast<Tex2D*>(tex) ) {
00338 tex2D->copyToTex2D();
00339 }
00340 }
00341 }
00342
00343
00344
00345
00346 #ifdef GLIFT_NRRD
00347
00348
00349
00350
00351
00352
00353
00354
00355
00356
00357
00358 GliftFormat format = nrrdTypePNM_glift(nIn);
00359 if( format == GliftFormatPGM ) { // PGM
00360 dimen.x = nIn->axis[0].size;
00361 dimen.y = nIn->axis[1].size;
00362 }
00363 else if( format == GliftFormatPPM ) { // PPM
00364 dimen.x = nIn->axis[1].size;
00365 dimen.y = nIn->axis[2].size;
00366 }
00367 else {
00368 cerr << "readDimenPNM(...) Error:\n"
00369 << "\tUnknown data format. Only PGM and PPM files are recognized.\n";
00370 exit(1);
00371 }
00372 }
00373 else {
00374 cerr << "readDimenPNM(...) Error:\n"
00375 << "\tCannot read " << fileName << endl;
00376 }
00377
00378 nrrdNuke( nIn );
00379 return e;
00380 }*/
00381
00382
00383
00384
00385
00386
00387
00388
00389
00390
00391 int readDimenNrrd( const char* fileName, arrayo1i& dimen, bool& isPNM)
00392 {
00393
00394 Nrrd* nIn = nrrdNew();
00395
00396 int e = gliftNrrdLoadHeader( nIn, fileName );
00397
00398 if( !e ) {
00399
00400 GliftFormat format = gliftNrrdTypePNM(nIn);
00401
00402 if( format == GliftFormatPGM ) {
00403 dimen = arrayo1i( 3, (int)0);
00404 dimen[0] = nIn->axis[1].size;
00405 dimen[1] = nIn->axis[0].size;
00406 dimen[2] = 1;
00407 isPNM = true;
00408 }
00409 else if( format == GliftFormatPPM ) {
00410 dimen = arrayo1i( 3, (int)0 );
00411 dimen[0] = nIn->axis[2].size;
00412 dimen[1] = nIn->axis[1].size;
00413 dimen[2] = 3;
00414 isPNM = true;
00415 }
00416 else {
00417 dimen = arrayo1i( nIn->dim, (int)0 );
00418
00419
00420 for(int i=0; i < dimen.size(); i++) {
00421 int nrrdI = i;
00422 dimen[i] = nIn->axis[ nrrdI ].size;
00423 }
00424 isPNM = false;
00425 }
00426 }
00427 else {
00428 cerr << "readDimenNrrd(...) Error:\n"
00429 << "\tCannot read " << fileName
00430 << biffGetDone(NRRD) << endl;
00431 }
00432
00433 nrrdNuke( nIn );
00434 return e;
00435 }
00436
00437
00438
00439
00440
00441
00442
00443
00444
00445 int loadPNM( GLenum channels, bool makeScalar, const char* inFileName, gutz::arrayo3ub& data )
00446 {
00447 int e = 0;
00448 int numChannels = getNumChannels(channels);
00449 vec3i newDim;
00450 vec3i minV(0,0,0);
00451 vec3i maxV;
00452
00453
00454 Nrrd* nIn = nrrdNew();
00455 nerr( nrrdLoad(nIn, inFileName), e );
00456
00457 if( e ) {
00458 cerr << "loadPNM(...) Error:\n"
00459 << biffGetDone(NRRD) << endl;
00460 return e;
00461 }
00462
00463
00464 GliftFormat format = gliftNrrdTypePNM(nIn);
00465
00466
00467 Nrrd* nOut = nrrdNew();
00468 if( format == GliftFormatPGM ) {
00469 newDim.x = nIn->axis[0].size;
00470 newDim.y = nIn->axis[1].size;
00471 newDim.z = numChannels;
00472 maxV = vec3i( numChannels-1, newDim.x-1, newDim.y-1 );
00473
00474
00475 Nrrd* nT1 = nrrdNew();
00476 nerr( nrrdFlip(nT1, nIn, 1), e );
00477 nerr( nrrdPad( nOut, nT1, minV.v(), maxV.v(), nrrdBoundaryBleed ), e );
00478 nrrdNuke( nT1 );
00479 }
00480 else if( format == GliftFormatPPM ) {
00481 newDim.x = nIn->axis[1].size;
00482 newDim.y = nIn->axis[2].size;
00483 newDim.z = numChannels;
00484 maxV = vec3i( numChannels-1, newDim.x-1, newDim.y-1 );
00485
00486 Nrrd* nT1 = nrrdNew();
00487 nerr( nrrdFlip(nT1, nIn, 2), e );
00488
00489 if( makeScalar ) {
00490
00491 int axis = 0;
00492 nerr( nrrdProject( nOut, nT1, axis, nrrdMeasureMean), e );
00493 nerr( nrrdReshape( nOut, nOut, 3, 1, newDim.x, newDim.y), e );
00494
00495 if( numChannels > 1 ) {
00496 nerr( nrrdPad( nT1, nOut, minV.v(), maxV.v(), nrrdBoundaryBleed ), e );
00497 nerr( nrrdCopy( nOut, nT1 ), e );
00498 }
00499 }
00500 else {
00501 if( numChannels == 1 || numChannels == 2 ) {
00502 nrrdCrop(nOut, nT1, minV.v(), maxV.v() );
00503 }
00504 else if( numChannels == 3 ) {
00505 nerr( nrrdCopy( nOut, nT1 ), e);
00506 }
00507 else if( numChannels == 4 ) {
00508 nerr( nrrdPad( nOut, nT1, minV.v(), maxV.v(), nrrdBoundaryPad, 255 ), e );
00509 }
00510 }
00511
00512 nrrdNuke( nT1 );
00513 }
00514
00515 if( !e ) {
00516
00517
00518
00519
00520 data.transfer( newDim.y, newDim.x, newDim.z, (uchar*)nOut->data, false );
00521 }
00522 else {
00523 cerr << "loadPNM(...) Error\n"
00524 << biffGetDone(NRRD) << endl
00525 << "\tError processing input. No data returned.\n";
00526 }
00527
00528
00529 nrrdNix( nOut );
00530 nrrdNix( nIn );
00531
00532 return e;
00533 }
00534
00535
00536
00537
00538
00539
00540
00541
00542 int loadNrrd3D( GLenum channels, const char* inFileName, arrayo4ub& data )
00543 {
00544 int e = 0;
00545 int numChannels = getNumChannels(channels);
00546
00547
00548 Nrrd* nIn = nrrdNew();
00549 nerr( nrrdLoad(nIn, inFileName), e );
00550
00551 if( e ) {
00552 cerr << "loadNrrd3D(...) Error:\n"
00553 << biffGetDone(NRRD) << endl;
00554 return e;
00555 }
00556
00557 if( nIn->dim != 3 &&
00558 !(nIn->dim == 4 && nIn->axis[3].size == 1) ) {
00559 cerr << "loadNrrd3D(...) Error:\n"
00560 << "\t" << inFileName << " is not a scalar volume file.\n";
00561 return e;
00562 }
00563
00564 if( nIn->type != nrrdTypeUChar ) {
00565 cerr << "loadNrrd3D(...) Error:\n"
00566 << "\t" << inFileName << " is not in unsigned byte format.\n";
00567 return e;
00568 }
00569
00570
00571
00572 vec4i newDim;
00573 newDim.x = nIn->axis[0].size;
00574 newDim.y = nIn->axis[1].size;
00575 newDim.z = nIn->axis[2].size;
00576 newDim.w = numChannels;
00577
00578 vec4i minV( 0, 0, 0, 0);
00579 vec4i maxV( numChannels-1, newDim.x-1, newDim.y-1, newDim.z-1 );
00580
00581
00582 Nrrd* nOut = nrrdNew();
00583 Nrrd* nT1 = nrrdNew();
00584
00585 nerr( nrrdFlip(nT1, nIn, 1), e );
00586
00587
00588 int newDimen = 4;
00589 nerr( nrrdReshape( nIn, nT1, newDimen, 1, newDim.x, newDim.y, newDim.z ), e );
00590 nerr( nrrdPad( nOut, nIn, minV.v(), maxV.v(), nrrdBoundaryBleed ), e );
00591
00592 nrrdNuke( nT1 );
00593
00594 if( !e ) {
00595
00596
00597
00598
00599 data.transfer( newDim.z, newDim.y, newDim.x, newDim.w, (uchar*)nOut->data, false );
00600 }
00601 else {
00602 cerr << "loadNrrd3D(...) Error\n"
00603 << biffGetDone(NRRD) << endl
00604 << "\tError processing input. No data returned.\n";
00605 }
00606
00607
00608 nrrdNix( nOut );
00609 nrrdNuke( nIn );
00610
00611 return e;
00612 }
00613
00614
00615 void writeFBtoPPM( GLenum channels, const vec2i& origin, const vec2i& dimen,
00616 char* baseFileName, bool sepChannels )
00617 {
00618 int numChannels = getNumChannels(channels);
00619 long numElts = dimen.x * dimen.y * numChannels;
00620 GLubyte* tempImage = new GLubyte[numElts];
00621 glReadPixels(0, 0, dimen.x, dimen.y, channels, GL_UNSIGNED_BYTE, tempImage );
00622
00623 arrayw3ub data( dimen.y, dimen.x, numChannels, tempImage );
00624 writePNM( baseFileName, data, sepChannels );
00625 delete tempImage;
00626 }
00627
00628
00629
00630
00631
00632 void writePNM( char* baseFileName, const arrayw3ub& data, bool sepChannels )
00633 {
00634 ubyte* imageData = (ubyte*)data.data();
00635 vec2i dimen( data.dim(1), data.dim(0) );
00636 int numChannels = data.dim(2);
00637 int numFiles = 1;
00638
00639 string baseName( baseFileName );
00640 vector<string> fileName(numChannels);
00641
00642 vector<Nrrd*> nOut(numChannels,(Nrrd*)NULL);
00643 Nrrd* nIn = nrrdNew();
00644 int e = 0;
00645
00646
00647 int i;
00648 for(i=0; i < numChannels; i++) {
00649 nOut[i] = nrrdNew();
00650 }
00651
00652
00653 if( numChannels == 1 ) {
00654 fileName[0] = baseName + ".pgm";
00655
00656
00657 nerr( nrrdWrap( nIn, imageData, nrrdTypeUChar, 2, dimen.x, dimen.y), e );
00658 nerr( nrrdFlip( nOut[0], nIn, 1 ), e );
00659 nrrdNix( nIn );
00660 }
00661 else {
00662 Nrrd* nT1 = nrrdNew();
00663 nerr( nrrdWrap( nT1, imageData, nrrdTypeUChar, 3, numChannels, dimen.x, dimen.y ), e);
00664 nerr( nrrdFlip( nIn, nT1, 2 ), e );
00665 nrrdNix( nT1 );
00666
00667 if( numChannels == 2 ) {
00668
00669
00670 if( sepChannels ) {
00671 numFiles = 2;
00672 fileName[0] = baseName + "R.pgm";
00673 fileName[1] = baseName + "G.pgm";
00674
00675 int axis = 0;
00676 nerr( nrrdSlice( nOut[0], nIn, axis, 0 ), e );
00677 nerr( nrrdSlice( nOut[1], nIn, axis, 1 ), e );
00678 }
00679 else {
00680 numFiles = 1;
00681 fileName[0] = baseName + ".ppm";
00682
00683
00684 vec3i minV(0,0,0);
00685 vec3i maxV( 2, dimen.x-1, dimen.y-1 );
00686 int padVal = 0;
00687
00688 nerr( nrrdPad( nOut[0], nIn, minV.v(), maxV.v(), nrrdBoundaryPad, padVal), e );
00689 }
00690 }
00691 else if( numChannels == 3 ) {
00692 if( sepChannels ) {
00693 numFiles = 3;
00694 fileName[0] = baseName + "R.pgm";
00695 fileName[1] = baseName + "G.pgm";
00696 fileName[2] = baseName + "B.pgm";
00697
00698 int axis = 0;
00699 nerr( nrrdSlice( nOut[0], nIn, axis, 0 ), e );
00700 nerr( nrrdSlice( nOut[1], nIn, axis, 1 ), e );
00701 nerr( nrrdSlice( nOut[2], nIn, axis, 2 ), e );
00702 }
00703 else {
00704 numFiles = 1;
00705 fileName[0] = baseName + ".ppm";
00706 nOut[0] = nIn;
00707 }
00708 }
00709 else if( numChannels == 4 ) {
00710 if( sepChannels ) {
00711 numFiles = 4;
00712 fileName[0] = baseName + "R.pgm";
00713 fileName[1] = baseName + "G.pgm";
00714 fileName[2] = baseName + "B.pgm";
00715 fileName[3] = baseName + "A.pgm";
00716
00717 int axis = 0;
00718 nerr( nrrdSlice( nOut[0], nIn, axis, 0 ), e );
00719 nerr( nrrdSlice( nOut[1], nIn, axis, 1 ), e );
00720 nerr( nrrdSlice( nOut[2], nIn, axis, 2 ), e );
00721 nerr( nrrdSlice( nOut[3], nIn, axis, 3 ), e );
00722 }
00723 else {
00724 numFiles = 2;
00725 fileName[0] = baseName + "RGB.ppm";
00726 fileName[1] = baseName + "A.pgm";
00727
00728
00729 vec3i minV(0,0,0);
00730 vec3i maxV( 2, dimen.x-1, dimen.y-1 );
00731
00732 nerr( nrrdCrop( nOut[0], nIn, minV.v(), maxV.v() ), e );
00733
00734
00735 int axis = 0;
00736 nerr( nrrdSlice( nOut[1], nIn, axis, 3 ), e );
00737 }
00738 }
00739 else {
00740 cerr << "writePNM(...) Error\n"
00741 << "\tChannels cannot equal " << numChannels << endl
00742 << "\tNo file written.\n";
00743 }
00744
00745 nrrdNuke( nIn );
00746 }
00747
00748
00749 if(e) {
00750 cerr << "writePNM(...) Error\n"
00751 << biffGetDone(NRRD) << endl;
00752 }
00753
00754
00755 for(i=0; i < numFiles; i++) {
00756 nrrdSave( fileName[i].c_str(), nOut[i], NULL );
00757 }
00758
00759
00760 for(i=0; i < numChannels; i++) {
00761 if( nOut[i] ) {
00762 nrrdNuke( nOut[i] );
00763 }
00764 }
00765 }
00766
00767
00768
00769 void writeNrrd3D( const char* baseFileName, const arrayw4ub& data )
00770 {
00771 vec3i dimen( data.dim(2), data.dim(1), data.dim(0) );
00772 int numChannels = data.dim(3);
00773
00774 Nrrd* nWrap = nrrdNew();
00775 int e = nrrdWrap( nWrap, (ubyte*)data.data(), nrrdTypeUChar,
00776 4, dimen.x, dimen.y, dimen.z, numChannels );
00777
00778 Nrrd* nOut = nrrdNew();
00779 nerr( nrrdFlip( nOut, nWrap, 1 ), e );
00780
00781
00782 if(e) {
00783 cerr << "writeNrrd3D(...) Error\n"
00784 << biffGetDone(NRRD) << endl;
00785 }
00786
00787
00788 string fileName = baseFileName + string(".nrrd");
00789 nerr( nrrdSave( fileName.c_str(), nOut, NULL ), e );
00790
00791 if( e ) {
00792 cerr << "gliftUtil::writeNrrd3D(...) Error : \n\t"
00793 << "Cannot write file \"" << fileName << "\" because\n\t"
00794 << biffGetDone(NRRD) << endl;
00795 }
00796
00797
00798 nrrdNix( nWrap );
00799 nrrdNuke(nOut );
00800 }
00801
00802
00803
00804
00805
00806 arrayw4ub packScalarToRGB( const arrayw4ub& data, int sizeZ )
00807 {
00808 assert( sizeZ <= data.dim(0) );
00809 assert( sizeZ % 3 == 0 );
00810 assert( data.dim(3) == 1 );
00811
00812 int e = 0;
00813 int numChannels = 1;
00814 vec3i dim( data.dim(2), data.dim(1), sizeZ );
00815 int zPacked = sizeZ/3;
00816
00817
00818
00819 Nrrd* nIn = nrrdNew();
00820 nerr( nrrdWrap( nIn, (ubyte*)data.data(), nrrdTypeUChar,
00821 4, numChannels, dim.x, dim.y, dim.z ), e );
00822
00823
00824 Nrrd** nSlab = new Nrrd*[zPacked];
00825 Nrrd* nOut = nrrdNew();
00826
00827 vec4i minV( 0, 0, 0, 0 );
00828 vec4i maxV( 0, dim.x-1, dim.y-1, 2 );
00829 int z;
00830 for(z=0; z < zPacked; z++) {
00831 nSlab[z] = nrrdNew();
00832 minV[3] = z*3;
00833 maxV[3] = (z+1)*3 - 1;
00834 nerr( nrrdCrop( nOut, nIn, minV.v(), maxV.v() ), e );
00835 nerr( nrrdAxesSwap( nSlab[z], nOut, 0, 3 ), e );
00836 }
00837
00838
00839 int joinAxis = 3;
00840 nerr( nrrdJoin( nOut, nSlab, zPacked, joinAxis, false ), e );
00841
00842
00843 arrayw4ub outData( zPacked, dim.y, dim.x, 3, (ubyte*)nOut->data );
00844
00845
00846 for(z=0; z < zPacked; z++) {
00847 nrrdNuke(nSlab[z]);
00848 }
00849 delete nSlab;
00850 nrrdNix(nIn);
00851 nrrdNix(nOut);
00852
00853 if(e) {
00854 cerr << "SolverRLS::initPhiDenseMem(...) Nrrd Error:\n\t"
00855 << biffGetDone(NRRD) << endl;
00856 exit(1);
00857 }
00858
00859 return outData;
00860 }
00861
00862
00863
00864
00865
00866 gutz::arrayw4ub unpackRGBToScalar( const gutz::arrayw4ub& data, int unpackZ )
00867 {
00868 assert( unpackZ <= data.dim(0)*3 );
00869 assert( data.dim(3) == 3 );
00870
00871 int e = 0;
00872 int numPackChannels = 3;
00873 vec3i packDim( data.dim(2), data.dim(1), data.dim(0) );
00874 vec3i upackDim(data.dim(2), data.dim(2), unpackZ );
00875
00876
00877
00878 Nrrd* nIn = nrrdNew();
00879 nerr( nrrdWrap( nIn, (ubyte*)data.data(), nrrdTypeUChar,
00880 4, numPackChannels, packDim.x, packDim.y, packDim.z ), e );
00881
00882
00883 Nrrd** nSlab = new Nrrd*[packDim.z];
00884 Nrrd* nOut = nrrdNew();
00885
00886 vec4i minV( 0, 0, 0, 0 );
00887 vec4i maxV( 2, packDim.x-1, packDim.y-1, 1 );
00888 int z;
00889 for(z=0; z < packDim.z; z++) {
00890 nSlab[z] = nrrdNew();
00891 minV[3] = z;
00892 maxV[3] = z;
00893 nerr( nrrdCrop( nOut, nIn, minV.v(), maxV.v() ), e );
00894 nerr( nrrdAxesSwap( nSlab[z], nOut, 0, 3 ), e );
00895 }
00896
00897
00898 int joinAxis = 3;
00899 nerr( nrrdJoin( nOut, nSlab, packDim.z, joinAxis, false ), e );
00900 int newZ = nOut->axis[3].size;
00901
00902
00903 if( upackDim.z < newZ ) {
00904 minV = vec4i(0,0,0,0);
00905 maxV = vec4i(0, upackDim.x-1, upackDim.y-1, upackDim.z-1);
00906 nerr( nrrdCrop( nSlab[0], nOut, minV.v(), maxV.v() ), e );
00907 nerr( nrrdCopy( nOut, nSlab[0]), e);
00908 }
00909
00910
00911 arrayw4ub outData( upackDim.z, upackDim.y, upackDim.x, 1, (ubyte*)nOut->data );
00912
00913
00914 for(z=0; z < packDim.z; z++) {
00915 nrrdNuke(nSlab[z]);
00916 }
00917 delete nSlab;
00918 nrrdNix(nIn);
00919 nrrdNix(nOut);
00920
00921 if(e) {
00922 cerr << "SolverRLS::initPhiDenseMem(...) Nrrd Error:\n\t"
00923 << biffGetDone(NRRD) << endl;
00924 exit(1);
00925 }
00926
00927 return outData;
00928 }
00929
00930
00931 #endif //GLIFT_NRRD
00932
00933