diff --git a/src/osgPlugins/bmp/ReaderWriterBMP.cpp b/src/osgPlugins/bmp/ReaderWriterBMP.cpp index 92f7228f7..79a5f852c 100644 --- a/src/osgPlugins/bmp/ReaderWriterBMP.cpp +++ b/src/osgPlugins/bmp/ReaderWriterBMP.cpp @@ -135,7 +135,7 @@ void swapbyte(short *i) vv[1]=tmp; } -unsigned char *bmp_load(const char *filename, +unsigned char *bmp_load(std::istream& fin, int *width_ret, int *height_ret, int *numComponents_ret) @@ -150,12 +150,10 @@ int *numComponents_ret) long filelen; bmperror = ERROR_NO_FILE; - FILE *fp = fopen(filename, "rb"); - if (!fp) return NULL; - fseek(fp, 0, SEEK_END); - filelen = ftell(fp); // determine file size so we can fill it in later if FileSize == 0 - fseek(fp, 0, SEEK_SET); + fin.seekg(0, std::ios::end); + filelen = fin.tellg(); // determine file size so we can fill it in later if FileSize == 0 + fin.seekg(0, std::ios::beg); int ncolours; int ncomp=0; @@ -165,7 +163,7 @@ int *numComponents_ret) struct bmpheader hd; struct BMPInfo inf; bmperror = ERROR_NO_ERROR; - fread((char *)&hd, sizeof(bmpheader), 1, fp); + fin.read((char*)&hd,sizeof(bmpheader)); if (hd.FileType != MB) { swapbyte(&(hd.FileType)); swap=true; @@ -177,15 +175,15 @@ int *numComponents_ret) int32 infsize; //size of BMPinfo in bytes unsigned char *cols=NULL; // dynamic colour palette unsigned char *imbuff; // returned to sender & as read from the disk - fread((char *)&infsize, sizeof(int32), 1, fp); // insert inside 'the file is bmp' clause + fin.read((char*)&infsize,sizeof(int32)); // insert inside 'the file is bmp' clause if (swap) swapbyte(&infsize); unsigned char *hdr=new unsigned char[infsize]; // to hold the new header - fread((char *)hdr, 1,infsize-sizeof(int32), fp); + fin.read((char*)hdr,infsize-sizeof(int32)); int32 hsiz=sizeof(inf); // minimum of structure size & if(infsize<=hsiz) hsiz=infsize; memcpy(&inf,hdr, hsiz/*-sizeof(long)*/); // copy only the bytes I can cope with delete [] hdr; - osg::notify(osg::INFO) << "loading "<setFileName(fileName.c_str()); pOsgImage->setImage(s,t,r, internalFormat, pixelFormat, @@ -363,15 +351,30 @@ class ReaderWriterBMP : public osgDB::ReaderWriter osg::Image::USE_NEW_DELETE); return pOsgImage; - } - virtual WriteResult writeImage(const osg::Image &img,const std::string& fileName, const osgDB::ReaderWriter::Options*) const - { - std::string ext = osgDB::getFileExtension(fileName); - if (!acceptsExtension(ext)) return WriteResult::FILE_NOT_HANDLED; - FILE *fp = fopen(fileName.c_str(), "wb"); - if (!fp) return WriteResult::ERROR_IN_WRITING_FILE; + virtual ReadResult readImage(std::istream& fin,const Options* =NULL) const + { + return readBMPStream(fin); + } + + virtual ReadResult readImage(const std::string& file, const osgDB::ReaderWriter::Options* options) const + { + std::string ext = osgDB::getLowerCaseFileExtension(file); + if (!acceptsExtension(ext)) return ReadResult::FILE_NOT_HANDLED; + + std::string fileName = osgDB::findDataFile( file, options ); + if (fileName.empty()) return ReadResult::FILE_NOT_FOUND; + + std::ifstream istream(fileName.c_str(), std::ios::in | std::ios::binary); + if(!istream) return ReadResult::FILE_NOT_HANDLED; + ReadResult rr = readBMPStream(istream); + if(rr.validImage()) rr.getImage()->setFileName(file); + return rr; + } + + bool WriteBMPStream(const osg::Image &img, std::ostream& fout, const std::string &fileName) const + { // its easier for me to write a binary write using stdio than streams struct bmpheader hd; uint32 nx=img.s(),ny=img.t(); // unsigned long ndep=img.r(); @@ -392,7 +395,7 @@ class ReaderWriterBMP : public osgDB::ReaderWriter hd.siz[0]=(size&0xffff); // low word hd.siz[1]=(size&0xffff0000)>>16; // high word - fwrite(&hd, sizeof(hd), 1, fp); + fout.write((const char*)&hd, sizeof(hd)); struct BMPInfo inf; osg::notify(osg::INFO) << "sizes "<"); + + if(success) + return WriteResult::FILE_SAVED; + else + return WriteResult::ERROR_IN_WRITING_FILE; + } + + virtual WriteResult writeImage(const osg::Image &img,const std::string& fileName, const osgDB::ReaderWriter::Options*) const + { + std::string ext = osgDB::getFileExtension(fileName); + if (!acceptsExtension(ext)) return WriteResult::FILE_NOT_HANDLED; + + std::ofstream fout(fileName.c_str(), std::ios::out | std::ios::binary); + if(!fout) return WriteResult::ERROR_IN_WRITING_FILE; + + bool success = WriteBMPStream(img, fout, fileName); + + if(success) + return WriteResult::FILE_SAVED; + else + return WriteResult::ERROR_IN_WRITING_FILE; } }; diff --git a/src/osgPlugins/gif/ReaderWriterGIF.cpp b/src/osgPlugins/gif/ReaderWriterGIF.cpp index d8ff75694..9203e45b0 100644 --- a/src/osgPlugins/gif/ReaderWriterGIF.cpp +++ b/src/osgPlugins/gif/ReaderWriterGIF.cpp @@ -133,9 +133,15 @@ int transparent) } } +int gif_read_stream(GifFileType *gfile, GifByteType *gdata, int glength) +{ + std::istream *stream = (std::istream*)gfile->UserData; //Get pointer to istream + stream->read((char*)gdata,glength); //Read requested amount of data + return stream->gcount(); +} unsigned char * -simage_gif_load(const char *filename, +simage_gif_load(std::istream& fin, int *width_ret, int *height_ret, int *numComponents_ret) @@ -154,7 +160,7 @@ int *numComponents_ret) int interlacedoffset[] = { 0, 4, 2, 1 }; int interlacedjumps[] = { 8, 8, 4, 2 }; - giffile = DGifOpenFileName(filename); + giffile = DGifOpen(&fin,gif_read_stream); if (!giffile) { giferror = ERR_OPEN; @@ -314,7 +320,6 @@ int *numComponents_ret) return buffer; } - class ReaderWriterGIF : public osgDB::ReaderWriter { public: @@ -324,20 +329,14 @@ class ReaderWriterGIF : public osgDB::ReaderWriter return osgDB::equalCaseInsensitive(extension,"gif"); } - virtual ReadResult readImage(const std::string& file, const osgDB::ReaderWriter::Options* options) const + ReadResult readGIFStream(std::istream& fin) const { - std::string ext = osgDB::getLowerCaseFileExtension(file); - if (!acceptsExtension(ext)) return ReadResult::FILE_NOT_HANDLED; - - std::string fileName = osgDB::findDataFile( file, options ); - if (fileName.empty()) return ReadResult::FILE_NOT_FOUND; - unsigned char *imageData = NULL; int width_ret; int height_ret; int numComponents_ret; - imageData = simage_gif_load(fileName.c_str(),&width_ret,&height_ret,&numComponents_ret); + imageData = simage_gif_load(fin,&width_ret,&height_ret,&numComponents_ret); switch (giferror) { @@ -366,7 +365,6 @@ class ReaderWriterGIF : public osgDB::ReaderWriter unsigned int dataType = GL_UNSIGNED_BYTE; osg::Image* pOsgImage = new osg::Image; - pOsgImage->setFileName(fileName.c_str()); pOsgImage->setImage(s,t,r, internalFormat, pixelFormat, @@ -375,7 +373,26 @@ class ReaderWriterGIF : public osgDB::ReaderWriter osg::Image::USE_NEW_DELETE); return pOsgImage; + } + virtual ReadResult readImage(std::istream& fin,const osgDB::ReaderWriter::Options* =NULL) const + { + return readGIFStream(fin); + } + + virtual ReadResult readImage(const std::string& file, const osgDB::ReaderWriter::Options* options) const + { + std::string ext = osgDB::getLowerCaseFileExtension(file); + if (!acceptsExtension(ext)) return ReadResult::FILE_NOT_HANDLED; + + std::string fileName = osgDB::findDataFile( file, options ); + if (fileName.empty()) return ReadResult::FILE_NOT_FOUND; + + std::ifstream istream(fileName.c_str(), std::ios::in | std::ios::binary); + if(!istream) return ReadResult::FILE_NOT_HANDLED; + ReadResult rr = readGIFStream(istream); + if(rr.validImage()) rr.getImage()->setFileName(file); + return rr; } }; diff --git a/src/osgPlugins/png/ReaderWriterPNG.cpp b/src/osgPlugins/png/ReaderWriterPNG.cpp index 57a0f0c67..a21e84169 100644 --- a/src/osgPlugins/png/ReaderWriterPNG.cpp +++ b/src/osgPlugins/png/ReaderWriterPNG.cpp @@ -30,22 +30,21 @@ typedef struct unsigned int Alpha; } pngInfo; +void png_read_istream(png_structp png_ptr, png_bytep data, png_size_t length) +{ + std::istream *stream = (std::istream*)png_get_io_ptr(png_ptr); //Get pointer to istream + stream->read((char*)data,length); //Read requested amount of data +} + class ReaderWriterPNG : public osgDB::ReaderWriter { public: virtual const char* className() const { return "PNG Image Reader/Writer"; } virtual bool acceptsExtension(const std::string& extension) const { return osgDB::equalCaseInsensitive(extension,"png"); } - virtual ReadResult readImage(const std::string& file, const osgDB::ReaderWriter::Options* options) const + ReadResult readPNGStream(std::istream& fin) const { - std::string ext = osgDB::getLowerCaseFileExtension(file); - if (!acceptsExtension(ext)) return ReadResult::FILE_NOT_HANDLED; - - std::string fileName = osgDB::findDataFile( file, options ); - if (fileName.empty()) return ReadResult::FILE_NOT_FOUND; - int trans = PNG_ALPHA; - FILE *fp = NULL; pngInfo pInfo; pngInfo *pinfo = &pInfo; @@ -65,9 +64,9 @@ class ReaderWriterPNG : public osgDB::ReaderWriter info = png_create_info_struct(png); endinfo = png_create_info_struct(png); - fp = fopen(fileName.c_str(), "rb"); - if (fp && fread(header, 1, 8, fp) && png_check_sig(header, 8)) - png_init_io(png, fp); + fin.read((char*)header,8); + if (fin.gcount() == 8 && png_check_sig(header, 8)) + png_set_read_fn(png,&fin,png_read_istream); //Use custom read function that will get data from istream else { png_destroy_read_struct(&png, &info, &endinfo); @@ -180,15 +179,11 @@ class ReaderWriterPNG : public osgDB::ReaderWriter // delete [] data; - if (fp) - fclose(fp); - if (pixelFormat==0) return ReadResult::FILE_NOT_HANDLED; osg::Image* pOsgImage = new osg::Image(); - pOsgImage->setFileName(fileName.c_str()); pOsgImage->setImage(width, height, 1, internalFormat, pixelFormat, @@ -198,6 +193,26 @@ class ReaderWriterPNG : public osgDB::ReaderWriter return pOsgImage; } + + virtual ReadResult readImage(std::istream& fin,const Options* =NULL) const + { + return readPNGStream(fin); + } + + virtual ReadResult readImage(const std::string& file, const osgDB::ReaderWriter::Options* options) const + { + std::string ext = osgDB::getLowerCaseFileExtension(file); + if (!acceptsExtension(ext)) return ReadResult::FILE_NOT_HANDLED; + + std::string fileName = osgDB::findDataFile( file, options ); + if (fileName.empty()) return ReadResult::FILE_NOT_FOUND; + + std::ifstream istream(fileName.c_str(), std::ios::in | std::ios::binary); + if(!istream) return ReadResult::FILE_NOT_HANDLED; + ReadResult rr = readPNGStream(istream); + if(rr.validImage()) rr.getImage()->setFileName(file); + return rr; + } }; // now register with Registry to instantiate the above diff --git a/src/osgPlugins/tga/ReaderWriterTGA.cpp b/src/osgPlugins/tga/ReaderWriterTGA.cpp index 1cb8a13bc..c1ebe633a 100644 --- a/src/osgPlugins/tga/ReaderWriterTGA.cpp +++ b/src/osgPlugins/tga/ReaderWriterTGA.cpp @@ -243,12 +243,11 @@ const int rleEntrySize) unsigned char * -simage_tga_load(const char *filename, +simage_tga_load(std::istream& fin, int *width_ret, int *height_ret, int *numComponents_ret) { - FILE * fp; unsigned char header[18]; int type; int width; @@ -269,17 +268,10 @@ int *numComponents_ret) tgaerror = ERR_NO_ERROR; /* clear error */ - fp = fopen(filename, "rb"); - if (!fp) - { - tgaerror = ERR_OPEN; - return NULL; - } - - if (fread(header, 1, 18, fp) != 18) + fin.read((char*)header,18); + if (fin.gcount() != 18) { tgaerror = ERR_READ; - fclose(fp); return NULL; } @@ -296,12 +288,11 @@ int *numComponents_ret) (depth < 2 || depth > 4)) { tgaerror = ERR_UNSUPPORTED; - fclose(fp); return NULL; } if (header[0]) /* skip identification field */ - fseek(fp, header[0], SEEK_CUR); + fin.seekg(header[0],std::ios::cur); colormap = NULL; if (header[1] == 1) /* there is a colormap */ @@ -309,7 +300,7 @@ int *numComponents_ret) int len = getInt16(&header[5]); indexsize = header[7]>>3; colormap = new unsigned char [len*indexsize]; - fread(colormap, 1, len*indexsize, fp); + fin.read((char*)colormap,len*indexsize); } if (depth == 2) /* 16 bits */ @@ -353,7 +344,8 @@ int *numComponents_ret) int x, y; for (y = 0; y < height; y++) { - if (fread(linebuf, 1, width*depth, fp) != (unsigned int)width*depth) + fin.read((char*)linebuf,width*depth); + if (fin.gcount() != (unsigned int)width*depth) { tgaerror = ERR_READ; break; @@ -380,10 +372,10 @@ int *numComponents_ret) int size, x, y; unsigned char *buf; unsigned char *src; - int pos = ftell(fp); - fseek(fp, 0, SEEK_END); - size = ftell(fp) - pos; - fseek(fp, pos, SEEK_SET); + int pos = fin.tellg(); + fin.seekg(0,std::ios::end); + size = (int)fin.tellg() - pos; + fin.seekg(pos,std::ios::beg); buf = new unsigned char [size]; if (buf == NULL) { @@ -391,7 +383,8 @@ int *numComponents_ret) break; } src = buf; - if (fread(buf, 1, size, fp) != (unsigned int) size) + fin.read((char*)buf,size); + if (fin.gcount() != (unsigned int) size) { tgaerror = ERR_READ; break; @@ -415,7 +408,6 @@ int *numComponents_ret) } if (linebuf) delete [] linebuf; - fclose(fp); if (tgaerror) { @@ -478,20 +470,14 @@ class ReaderWriterTGA : public osgDB::ReaderWriter virtual const char* className() const { return "TGA Image Reader"; } virtual bool acceptsExtension(const std::string& extension) const { return osgDB::equalCaseInsensitive(extension,"tga"); } - virtual ReadResult readImage(const std::string& file, const osgDB::ReaderWriter::Options* options) const + ReadResult readTGAStream(std::istream& fin) const { - std::string ext = osgDB::getLowerCaseFileExtension(file); - if (!acceptsExtension(ext)) return ReadResult::FILE_NOT_HANDLED; - - std::string fileName = osgDB::findDataFile( file, options ); - if (fileName.empty()) return ReadResult::FILE_NOT_FOUND; - unsigned char *imageData = NULL; int width_ret; int height_ret; int numComponents_ret; - imageData = simage_tga_load(fileName.c_str(),&width_ret,&height_ret,&numComponents_ret); + imageData = simage_tga_load(fin,&width_ret,&height_ret,&numComponents_ret); if (imageData==NULL) return ReadResult::FILE_NOT_HANDLED; @@ -510,7 +496,6 @@ class ReaderWriterTGA : public osgDB::ReaderWriter unsigned int dataType = GL_UNSIGNED_BYTE; osg::Image* pOsgImage = new osg::Image; - pOsgImage->setFileName(fileName.c_str()); pOsgImage->setImage(s,t,r, internalFormat, pixelFormat, @@ -521,6 +506,26 @@ class ReaderWriterTGA : public osgDB::ReaderWriter return pOsgImage; } + + virtual ReadResult readImage(std::istream& fin,const Options* =NULL) const + { + return readTGAStream(fin); + } + + virtual ReadResult readImage(const std::string& file, const osgDB::ReaderWriter::Options* options) const + { + std::string ext = osgDB::getLowerCaseFileExtension(file); + if (!acceptsExtension(ext)) return ReadResult::FILE_NOT_HANDLED; + + std::string fileName = osgDB::findDataFile( file, options ); + if (fileName.empty()) return ReadResult::FILE_NOT_FOUND; + + std::ifstream istream(fileName.c_str(), std::ios::in | std::ios::binary); + if(!istream) return ReadResult::FILE_NOT_HANDLED; + ReadResult rr = readTGAStream(istream); + if(rr.validImage()) rr.getImage()->setFileName(file); + return rr; + } }; // now register with Registry to instantiate the above