00001 #include "FileSystemImageSource.h"
00002 #include "Shared/ImageUtil.h"
00003 #include "Shared/debuget.h"
00004 #include <sys/types.h>
00005 #include <sys/mman.h>
00006
00007
00008 using namespace std;
00009
00010 void FileSystemImageSource::ImageInfo::prepare() {
00011 if(prepared)
00012 return;
00013 if(data==NULL) {
00014
00015 FileInfo::prepare();
00016 if(data==NULL)
00017 return;
00018
00019
00020 width=height=components=0;
00021 size_t totalSize=0;
00022 char * imgbuf = ((char*)NULL)-1;
00023 image_util::decodeImage(data,size,width,height,components,imgbuf,totalSize);
00024 size_t headerSize=getHeaderSize();
00025 totalSize = headerSize + width*height*components;
00026
00027 imgbuf = static_cast<char*>(mmap(NULL,totalSize,PROT_READ|PROT_WRITE,MAP_PRIVATE|MAP_ANON,-1,0));
00028 if(imgbuf==MAP_FAILED) {
00029 std::string err="FileSystemImageSource::ImageInfo::prepare() unable to mmap allocation for image decompression of ";
00030 err+=filename;
00031 perror(err.c_str());
00032 FileInfo::release();
00033 return;
00034 }
00035 if(writeHeader(imgbuf,headerSize)==0) {
00036 cerr << "FileSystemImageSource::ImageInfo::prepare(): Ran out of space writing image header" << endl;
00037 munmap(imgbuf,totalSize);
00038 FileInfo::release();
00039 return;
00040 }
00041
00042
00043 char * img=imgbuf+headerSize;
00044 size_t imgSize=totalSize-headerSize;
00045 if(!image_util::decodeImage(data,size,width,height,components,img,imgSize)) {
00046 cerr << "Image decompression failed for " << filename << endl;
00047 munmap(imgbuf,totalSize);
00048 FileInfo::release();
00049 return;
00050 }
00051
00052
00053 FileInfo::release();
00054 data=imgbuf;
00055 size=totalSize;
00056 }
00057 FileInfo::prepare();
00058 }
00059
00060 size_t FileSystemImageSource::ImageInfo::getHeaderSize() const {
00061 return LoadSave::getSerializedSize<unsigned int>()*4;
00062 }
00063
00064 size_t FileSystemImageSource::ImageInfo::writeHeader(char* buf, size_t sz) const {
00065 unsigned int remain=sz;
00066 if(!LoadSave::encodeInc(*dataSource.layer,buf,remain)) return 0;
00067 if(!LoadSave::encodeInc(width,buf,remain)) return 0;
00068 if(!LoadSave::encodeInc(height,buf,remain)) return 0;
00069 if(!LoadSave::encodeInc(components,buf,remain)) return 0;
00070 ASSERT(remain==0,"FileSystemImageSource::ImageInfo::writeHeader(): Leftover bytes in header? getHeaderSize() is wrong\n");
00071 return sz-remain;
00072 }
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083