1 // Released under the OSGPL license, as part of the OpenSceneGraph distribution.
2 //
3 // ReaderWriter for sgi's .rgb format.
4 // specification can be found at http://local.wasp.uwa.edu.au/~pbourke/dataformats/sgirgb/sgiversion.html
5
6 #include <osg/Image>
7 #include <osg/Notify>
8
9 #include <osg/Geode>
10
11 #include <osg/GL>
12
13 #include <osgDB/FileNameUtils>
14 #include <osgDB/FileUtils>
15 #include <osgDB/Registry>
16
17 #include <stdio.h>
18 #include <stdlib.h>
19 #include <string.h>
20
21 #ifndef SEEK_SET
22 # define SEEK_SET 0
23 #endif
24
25 #if defined(OSG_GLES1_AVAILABLE) || defined(OSG_GLES2_AVAILABLE)
26 #define GL_BITMAP 0x1A00
27 #define GL_RED 0x1903
28 #define GL_GREEN 0x1904
29 #define GL_BLUE 0x1905
30 #define GL_COLOR_INDEX 0x1900
31 #endif
32
33 #if defined(OSG_GL3_AVAILABLE)
34 #define GL_BITMAP 0x1A00
35 #define GL_COLOR_INDEX 0x1900
36 #endif
37
38 using namespace osg;
39
40
41 typedef struct _rawImageRec
42 {
43 unsigned short imagic;
44 unsigned short type;
45 unsigned short dim;
46 unsigned short sizeX, sizeY, sizeZ;
47 unsigned long min, max;
48 unsigned long wasteBytes;
49 char name[80];
50 unsigned long colorMap;
51 std::istream *file;
52 unsigned char *tmp, *tmpR, *tmpG, *tmpB, *tmpA;
53 unsigned long rleEnd;
54 GLuint *rowStart;
55 GLint *rowSize;
56 GLenum swapFlag;
57 short bpc;
58
59 typedef unsigned char * BytePtr;
60
needsBytesSwapped_rawImageRec61 bool needsBytesSwapped()
62 {
63 union {
64 int testWord;
65 char testByte[sizeof(int)];
66 }endianTest;
67 endianTest.testWord = 1;
68 if( endianTest.testByte[0] == 1 )
69 return true;
70 else
71 return false;
72 }
73
74 template <class T>
swapBytes_rawImageRec75 inline void swapBytes( T &s )
76 {
77 if( sizeof( T ) == 1 )
78 return;
79
80 T d = s;
81 BytePtr sptr = (BytePtr)&s;
82 BytePtr dptr = &(((BytePtr)&d)[sizeof(T)-1]);
83
84 for( unsigned int i = 0; i < sizeof(T); i++ )
85 *(sptr++) = *(dptr--);
86 }
87
swapBytes_rawImageRec88 void swapBytes()
89 {
90 swapBytes( imagic );
91 swapBytes( type );
92 swapBytes( dim );
93 swapBytes( sizeX );
94 swapBytes( sizeY );
95 swapBytes( sizeZ );
96 swapBytes( wasteBytes );
97 swapBytes( min );
98 swapBytes( max );
99 swapBytes( colorMap );
100 }
101 } rawImageRec;
102
ConvertShort(unsigned short * array,long length)103 static void ConvertShort(unsigned short *array, long length)
104 {
105 unsigned long b1, b2;
106 unsigned char *ptr;
107
108 ptr = (unsigned char *)array;
109 while (length--)
110 {
111 b1 = *ptr++;
112 b2 = *ptr++;
113 *array++ = (unsigned short) ((b1 << 8) | (b2));
114 }
115 }
116
ConvertLong(GLuint * array,long length)117 static void ConvertLong(GLuint *array, long length)
118 {
119 unsigned long b1, b2, b3, b4;
120 unsigned char *ptr;
121
122 ptr = (unsigned char *)array;
123 while (length--)
124 {
125 b1 = *ptr++;
126 b2 = *ptr++;
127 b3 = *ptr++;
128 b4 = *ptr++;
129 *array++ = (b1 << 24) | (b2 << 16) | (b3 << 8) | (b4);
130 }
131 }
132
133
RawImageClose(rawImageRec * raw)134 static void RawImageClose(rawImageRec *raw)
135 {
136 if (raw)
137 {
138
139 if (raw->tmp) delete [] raw->tmp;
140 if (raw->tmpR) delete [] raw->tmpR;
141 if (raw->tmpG) delete [] raw->tmpG;
142 if (raw->tmpB) delete [] raw->tmpB;
143 if (raw->tmpA) delete [] raw->tmpA;
144
145 if (raw->rowStart) delete [] raw->rowStart;
146 if (raw->rowSize) delete [] raw->rowSize;
147
148 delete raw;
149 }
150 }
151
152
RawImageOpen(std::istream & fin)153 static rawImageRec *RawImageOpen(std::istream& fin)
154 {
155 union
156 {
157 int testWord;
158 char testByte[4];
159 } endianTest;
160 rawImageRec *raw;
161 int x;
162
163 raw = new rawImageRec;
164 if (raw == NULL)
165 {
166 OSG_WARN<< "Out of memory!"<< std::endl;
167 return NULL;
168 }
169
170 //Set istream pointer
171 raw->file = &fin;
172
173 endianTest.testWord = 1;
174 if (endianTest.testByte[0] == 1)
175 {
176 raw->swapFlag = GL_TRUE;
177 }
178 else
179 {
180 raw->swapFlag = GL_FALSE;
181 }
182
183 fin.read((char*)raw,12);
184 if (!fin.good())
185 return NULL;
186
187 if (raw->swapFlag)
188 {
189 ConvertShort(&raw->imagic, 6);
190 }
191
192 raw->tmp = raw->tmpR = raw->tmpG = raw->tmpB = raw->tmpA = 0L;
193 raw->rowStart = 0;
194 raw->rowSize = 0;
195 raw->bpc = (raw->type & 0x00FF);
196
197 raw->tmp = new unsigned char [raw->sizeX*256*raw->bpc];
198 if (raw->tmp == NULL )
199 {
200 OSG_FATAL<< "Out of memory!"<< std::endl;
201 RawImageClose(raw);
202 return NULL;
203 }
204
205 if( raw->sizeZ >= 1 )
206 {
207 if( (raw->tmpR = new unsigned char [raw->sizeX*raw->bpc]) == NULL )
208 {
209 OSG_FATAL<< "Out of memory!"<< std::endl;
210 RawImageClose(raw);
211 return NULL;
212 }
213 }
214 if( raw->sizeZ >= 2 )
215 {
216 if( (raw->tmpG = new unsigned char [raw->sizeX*raw->bpc]) == NULL )
217 {
218 OSG_FATAL<< "Out of memory!"<< std::endl;
219 RawImageClose(raw);
220 return NULL;
221 }
222 }
223 if( raw->sizeZ >= 3 )
224 {
225 if( (raw->tmpB = new unsigned char [raw->sizeX*raw->bpc]) == NULL )
226 {
227 OSG_FATAL<< "Out of memory!"<< std::endl;
228 RawImageClose(raw);
229 return NULL;
230 }
231 }
232 if (raw->sizeZ >= 4)
233 {
234 if( (raw->tmpA = new unsigned char [raw->sizeX*raw->bpc]) == NULL )
235 {
236 OSG_FATAL<< "Out of memory!"<< std::endl;
237 RawImageClose(raw);
238 return NULL;
239 }
240 }
241
242 if ((raw->type & 0xFF00) == 0x0100)
243 {
244 unsigned int ybyz = raw->sizeY * raw->sizeZ;
245 if ( (raw->rowStart = new GLuint [ybyz]) == NULL )
246 {
247 OSG_FATAL<< "Out of memory!"<< std::endl;
248 RawImageClose(raw);
249 return NULL;
250 }
251
252 if ( (raw->rowSize = new GLint [ybyz]) == NULL )
253 {
254 OSG_FATAL<< "Out of memory!"<< std::endl;
255 RawImageClose(raw);
256 return NULL;
257 }
258 x = ybyz * sizeof(GLuint);
259 raw->rleEnd = 512 + (2 * x);
260 fin.seekg(512,std::ios::beg);
261 fin.read((char*)raw->rowStart,x);
262 fin.read((char*)raw->rowSize,x);
263 if (raw->swapFlag)
264 {
265 ConvertLong(raw->rowStart, (long) (x/sizeof(GLuint)));
266 ConvertLong((GLuint *)raw->rowSize, (long) (x/sizeof(GLint)));
267 }
268 }
269 return raw;
270 }
271
272
RawImageGetRow(rawImageRec * raw,unsigned char * buf,int y,int z)273 static void RawImageGetRow(rawImageRec *raw, unsigned char *buf, int y, int z)
274 {
275 unsigned char *iPtr, *oPtr;
276 unsigned short pixel;
277 int count, done = 0;
278 unsigned short *tempShort;
279
280 if ((raw->type & 0xFF00) == 0x0100)
281 {
282 raw->file->seekg((long) raw->rowStart[y+z*raw->sizeY], std::ios::beg);
283 raw->file->read((char*)raw->tmp, (unsigned int)raw->rowSize[y+z*raw->sizeY]);
284
285 iPtr = raw->tmp;
286 oPtr = buf;
287 while (!done)
288 {
289 if (raw->bpc == 1)
290 pixel = *iPtr++;
291 else
292 {
293 tempShort = reinterpret_cast<unsigned short*>(iPtr);
294 pixel = *tempShort;
295 tempShort++;
296 iPtr = reinterpret_cast<unsigned char *>(tempShort);
297 }
298
299 if(raw->bpc != 1)
300 ConvertShort(&pixel, 1);
301
302 count = (int)(pixel & 0x7F);
303
304 // limit the count value to the remiaing row size
305 if (raw->sizeX*raw->bpc <= (oPtr - buf))
306 {
307 count = raw->sizeX - (oPtr - buf) / raw->bpc;
308 }
309
310 if (count<=0)
311 {
312 done = 1;
313 return;
314 }
315
316 if (pixel & 0x80)
317 {
318 while (count--)
319 {
320 if(raw->bpc == 1)
321 *oPtr++ = *iPtr++;
322 else{
323 tempShort = reinterpret_cast<unsigned short*>(iPtr);
324 pixel = *tempShort;
325 tempShort++;
326 iPtr = reinterpret_cast<unsigned char *>(tempShort);
327
328 ConvertShort(&pixel, 1);
329
330 tempShort = reinterpret_cast<unsigned short*>(oPtr);
331 *tempShort = pixel;
332 tempShort++;
333 oPtr = reinterpret_cast<unsigned char *>(tempShort);
334 }
335 }
336 }
337 else
338 {
339 if (raw->bpc == 1)
340 {
341 pixel = *iPtr++;
342 }
343 else
344 {
345 tempShort = reinterpret_cast<unsigned short*>(iPtr);
346 pixel = *tempShort;
347 tempShort++;
348 iPtr = reinterpret_cast<unsigned char *>(tempShort);
349 }
350 if(raw->bpc != 1)
351 ConvertShort(&pixel, 1);
352 while (count--)
353 {
354 if(raw->bpc == 1)
355 *oPtr++ = pixel;
356 else
357 {
358 tempShort = reinterpret_cast<unsigned short*>(oPtr);
359 *tempShort = pixel;
360 tempShort++;
361 oPtr = reinterpret_cast<unsigned char *>(tempShort);
362 }
363 }
364 }
365 }
366 }
367 else
368 {
369 raw->file->seekg(512+(y*raw->sizeX*raw->bpc)+(z*raw->sizeX*raw->sizeY*raw->bpc),std::ios::beg);
370 raw->file->read((char*)buf, raw->sizeX*raw->bpc);
371 if(raw->swapFlag && raw->bpc != 1){
372 ConvertShort(reinterpret_cast<unsigned short*>(buf), raw->sizeX);
373 }
374 }
375 }
376
377
RawImageGetData(rawImageRec * raw,unsigned char ** data)378 static void RawImageGetData(rawImageRec *raw, unsigned char **data )
379 {
380 unsigned char *ptr;
381 int i, j;
382 unsigned short *tempShort;
383
384 // // round the width to a factor 4
385 // int width = (int)(floorf((float)raw->sizeX/4.0f)*4.0f);
386 // if (width!=raw->sizeX) width += 4;
387
388 // byte aligned.
389
390 OSG_INFO<<"raw->sizeX = "<<raw->sizeX<<std::endl;
391 OSG_INFO<<"raw->sizeY = "<<raw->sizeY<<std::endl;
392 OSG_INFO<<"raw->sizeZ = "<<raw->sizeZ<<std::endl;
393 OSG_INFO<<"raw->bpc = "<<raw->bpc<<std::endl;
394
395 *data = new unsigned char [(raw->sizeX)*(raw->sizeY)*(raw->sizeZ)*(raw->bpc)];
396
397 ptr = *data;
398 for (i = 0; i < (int)(raw->sizeY); i++)
399 {
400 if( raw->sizeZ >= 1 )
401 RawImageGetRow(raw, raw->tmpR, i, 0);
402 if( raw->sizeZ >= 2 )
403 RawImageGetRow(raw, raw->tmpG, i, 1);
404 if( raw->sizeZ >= 3 )
405 RawImageGetRow(raw, raw->tmpB, i, 2);
406 if( raw->sizeZ >= 4 )
407 RawImageGetRow(raw, raw->tmpA, i, 3);
408 for (j = 0; j < (int)(raw->sizeX); j++)
409 {
410 if(raw->bpc == 1){
411 if( raw->sizeZ >= 1 )
412 *ptr++ = *(raw->tmpR + j);
413 if( raw->sizeZ >= 2 )
414 *ptr++ = *(raw->tmpG + j);
415 if( raw->sizeZ >= 3 )
416 *ptr++ = *(raw->tmpB + j);
417 if( raw->sizeZ >= 4 )
418 *ptr++ = *(raw->tmpA + j);
419 }else{
420 if( raw->sizeZ >= 1 )
421 {
422 tempShort = reinterpret_cast<unsigned short*>(ptr);
423 *tempShort = *(reinterpret_cast<unsigned short*>(raw->tmpR) + j);
424 tempShort++;
425 ptr = reinterpret_cast<unsigned char *>(tempShort);
426 }
427 if( raw->sizeZ >= 2 )
428 {
429 tempShort = reinterpret_cast<unsigned short*>(ptr);
430 *tempShort = *(reinterpret_cast<unsigned short*>(raw->tmpG) + j);
431 tempShort++;
432 ptr = reinterpret_cast<unsigned char *>(tempShort);
433 }
434 if( raw->sizeZ >= 3 )
435 {
436 tempShort = reinterpret_cast<unsigned short*>(ptr);
437 *tempShort = *(reinterpret_cast<unsigned short*>(raw->tmpB) + j);
438 tempShort++;
439 ptr = reinterpret_cast<unsigned char *>(tempShort);
440 }
441 if( raw->sizeZ >= 4 )
442 {
443 tempShort = reinterpret_cast<unsigned short*>(ptr);
444 *tempShort = *(reinterpret_cast<unsigned short*>(raw->tmpA) + j);
445 tempShort++;
446 ptr = reinterpret_cast<unsigned char *>(tempShort);
447 }
448 }
449 }
450 // // pad the image width with blanks to bring it up to the rounded width.
451 // for(;j<width;++j) *ptr++ = 0;
452 }
453 }
454
455
456 class ReaderWriterRGB : public osgDB::ReaderWriter
457 {
458 public:
459
ReaderWriterRGB()460 ReaderWriterRGB()
461 {
462 supportsExtension("rgb","rgb image format");
463 supportsExtension("rgba","rgba image format");
464 supportsExtension("sgi","sgi image format");
465 supportsExtension("int","int image format");
466 supportsExtension("inta","inta image format");
467 supportsExtension("bw","bw image format");
468 }
469
className() const470 virtual const char* className() const { return "RGB Image Reader/Writer"; }
471
readRGBStream(std::istream & fin) const472 ReadResult readRGBStream(std::istream& fin) const
473 {
474 rawImageRec *raw;
475
476 if( (raw = RawImageOpen(fin)) == NULL )
477 {
478 return ReadResult::ERROR_IN_READING_FILE;
479 }
480
481 int s = raw->sizeX;
482 int t = raw->sizeY;
483 int r = 1;
484
485 unsigned int pixelFormat =
486 raw->sizeZ == 1 ? GL_LUMINANCE :
487 raw->sizeZ == 2 ? GL_LUMINANCE_ALPHA :
488 raw->sizeZ == 3 ? GL_RGB :
489 raw->sizeZ == 4 ? GL_RGBA : (GLenum)-1;
490
491 int internalFormat = pixelFormat;
492
493 unsigned int dataType = raw->bpc == 1 ? GL_UNSIGNED_BYTE :
494 GL_UNSIGNED_SHORT;
495
496 unsigned char *data;
497 RawImageGetData(raw, &data);
498 RawImageClose(raw);
499
500 Image* image = new Image();
501 image->setImage(s,t,r,
502 internalFormat,
503 pixelFormat,
504 dataType,
505 data,
506 osg::Image::USE_NEW_DELETE);
507
508 OSG_INFO << "image read ok "<<s<<" "<<t<< std::endl;
509 return image;
510 }
511
readObject(std::istream & fin,const osgDB::ReaderWriter::Options * options=NULL) const512 virtual ReadResult readObject(std::istream& fin,const osgDB::ReaderWriter::Options* options =NULL) const
513 {
514 return readImage(fin, options);
515 }
516
readObject(const std::string & file,const osgDB::ReaderWriter::Options * options=NULL) const517 virtual ReadResult readObject(const std::string& file, const osgDB::ReaderWriter::Options* options =NULL) const
518 {
519 return readImage(file, options);
520 }
521
readImage(std::istream & fin,const osgDB::ReaderWriter::Options * =NULL) const522 virtual ReadResult readImage(std::istream& fin,const osgDB::ReaderWriter::Options* =NULL) const
523 {
524 return readRGBStream(fin);
525 }
526
readImage(const std::string & file,const osgDB::ReaderWriter::Options * options) const527 virtual ReadResult readImage(const std::string& file, const osgDB::ReaderWriter::Options* options) const
528 {
529 std::string ext = osgDB::getLowerCaseFileExtension(file);
530 if (!acceptsExtension(ext)) return ReadResult::FILE_NOT_HANDLED;
531
532 std::string fileName = osgDB::findDataFile( file, options );
533 if (fileName.empty()) return ReadResult::FILE_NOT_FOUND;
534
535 osgDB::ifstream istream(fileName.c_str(), std::ios::in | std::ios::binary);
536 if(!istream) return ReadResult::FILE_NOT_HANDLED;
537 ReadResult rr = readRGBStream(istream);
538 if(rr.validImage()) rr.getImage()->setFileName(file);
539 return rr;
540 }
541
writeRGBStream(const osg::Image & img,std::ostream & fout,const std::string & name) const542 WriteResult writeRGBStream(const osg::Image& img, std::ostream &fout, const std::string& name) const
543 {
544 rawImageRec raw;
545 raw.imagic = 0732;
546
547 GLenum dataType = img.getDataType();
548
549 raw.type = dataType == GL_UNSIGNED_BYTE ? 1 :
550 dataType == GL_BYTE ? 1 :
551 dataType == GL_BITMAP ? 1 :
552 dataType == GL_UNSIGNED_SHORT ? 2 :
553 dataType == GL_SHORT ? 2 :
554 dataType == GL_UNSIGNED_INT ? 4 :
555 dataType == GL_INT ? 4 :
556 dataType == GL_FLOAT ? 4 :
557 dataType == GL_UNSIGNED_BYTE_3_3_2 ? 1 :
558 dataType == GL_UNSIGNED_BYTE_2_3_3_REV ? 1 :
559 dataType == GL_UNSIGNED_SHORT_5_6_5 ? 2 :
560 dataType == GL_UNSIGNED_SHORT_5_6_5_REV ? 2 :
561 dataType == GL_UNSIGNED_SHORT_4_4_4_4 ? 2 :
562 dataType == GL_UNSIGNED_SHORT_4_4_4_4_REV ? 2 :
563 dataType == GL_UNSIGNED_SHORT_5_5_5_1 ? 2 :
564 dataType == GL_UNSIGNED_SHORT_1_5_5_5_REV ? 2 :
565 dataType == GL_UNSIGNED_INT_8_8_8_8 ? 4 :
566 dataType == GL_UNSIGNED_INT_8_8_8_8_REV ? 4 :
567 dataType == GL_UNSIGNED_INT_10_10_10_2 ? 4 :
568 dataType == GL_UNSIGNED_INT_2_10_10_10_REV ? 4 : 4;
569
570 GLenum pixelFormat = img.getPixelFormat();
571
572 raw.dim = 3;
573 raw.sizeX = img.s();
574 raw.sizeY = img.t();
575 raw.sizeZ =
576 pixelFormat == GL_COLOR_INDEX? 1 :
577 pixelFormat == GL_RED? 1 :
578 pixelFormat == GL_GREEN? 1 :
579 pixelFormat == GL_BLUE? 1 :
580 pixelFormat == GL_ALPHA? 1 :
581 pixelFormat == GL_RGB? 3 :
582 pixelFormat == GL_BGR ? 3 :
583 pixelFormat == GL_RGBA? 4 :
584 pixelFormat == GL_BGRA? 4 :
585 pixelFormat == GL_LUMINANCE? 1 :
586 pixelFormat == GL_LUMINANCE_ALPHA ? 2 : 1;
587 raw.min = 0;
588 raw.max = 0xFF;
589 raw.wasteBytes = 0;
590 strncpy( raw.name, name.c_str(), 80);
591 raw.colorMap = 0;
592 raw.bpc = (img.getPixelSizeInBits()/raw.sizeZ)/8;
593
594 int isize = img.getImageSizeInBytes();
595 unsigned char *buffer = new unsigned char[isize];
596 if(raw.bpc == 1)
597 {
598 unsigned char *dptr = buffer;
599 int i, j;
600 for( i = 0; i < raw.sizeZ; ++i )
601 {
602 const unsigned char *ptr = img.data();
603 ptr += i;
604 for( j = 0; j < isize/raw.sizeZ; ++j )
605 {
606 *(dptr++) = *ptr;
607 ptr += raw.sizeZ;
608 }
609 }
610 }
611 else
612 { // bpc == 2
613 unsigned short *dptr = reinterpret_cast<unsigned short*>(buffer);
614 int i, j;
615 for( i = 0; i < raw.sizeZ; ++i )
616 {
617 const unsigned short *ptr = reinterpret_cast<const unsigned short*>(img.data());
618 ptr += i;
619 for( j = 0; j < isize/(raw.sizeZ*2); ++j )
620 {
621 *dptr = *ptr;
622 ConvertShort(dptr++, 1);
623 ptr += raw.sizeZ;
624 }
625 }
626 }
627
628
629 if( raw.needsBytesSwapped() )
630 raw.swapBytes();
631
632 /*
633 swapBytes( raw.imagic );
634 swapBytes( raw.type );
635 swapBytes( raw.dim );
636 swapBytes( raw.sizeX );
637 swapBytes( raw.sizeY );
638 swapBytes( raw.sizeZ );
639 swapBytes( raw.min );
640 swapBytes( raw.max );
641 swapBytes( raw.colorMap );
642 */
643
644
645 char pad[512 - sizeof(rawImageRec)];
646 memset( pad, 0, sizeof(pad));
647
648 fout.write((const char*)&raw,sizeof(rawImageRec));
649 fout.write((const char*)pad,sizeof(pad));
650 fout.write((const char*)buffer,isize);
651
652 delete [] buffer;
653
654 return WriteResult::FILE_SAVED;
655 }
656
writeImage(const osg::Image & img,std::ostream & fout,const osgDB::ReaderWriter::Options *) const657 virtual WriteResult writeImage(const osg::Image& img,std::ostream& fout,const osgDB::ReaderWriter::Options*) const
658 {
659 if (img.isCompressed())
660 {
661 OSG_NOTICE<<"Warning: RGB plugin does not supporting writing compressed imagery."<<std::endl;
662 return WriteResult::ERROR_IN_WRITING_FILE;
663 }
664 if (!img.isDataContiguous())
665 {
666 OSG_NOTICE<<"Warning: RGB plugin does not supporting writing non contiguous imagery."<<std::endl;
667 return WriteResult::ERROR_IN_WRITING_FILE;
668 }
669
670 return writeRGBStream(img,fout,"");
671 }
672
writeImage(const osg::Image & img,const std::string & fileName,const osgDB::ReaderWriter::Options *) const673 virtual WriteResult writeImage(const osg::Image &img,const std::string& fileName, const osgDB::ReaderWriter::Options*) const
674 {
675 if (img.isCompressed())
676 {
677 OSG_NOTICE<<"Warning: RGB plugin does not supporting writing compressed imagery."<<std::endl;
678 return WriteResult::ERROR_IN_WRITING_FILE;
679 }
680 if (!img.isDataContiguous())
681 {
682 OSG_NOTICE<<"Warning: RGB plugin does not supporting writing non contiguous imagery."<<std::endl;
683 return WriteResult::ERROR_IN_WRITING_FILE;
684 }
685
686 std::string ext = osgDB::getFileExtension(fileName);
687 if (!acceptsExtension(ext)) return WriteResult::FILE_NOT_HANDLED;
688
689 osgDB::ofstream fout(fileName.c_str(), std::ios::out | std::ios::binary);
690 if(!fout) return WriteResult::ERROR_IN_WRITING_FILE;
691
692 return writeRGBStream(img,fout,fileName);
693 }
694
695 };
696
697 // now register with Registry to instantiate the above
698 // reader/writer.
699 REGISTER_OSGPLUGIN(rgb, ReaderWriterRGB)
700