Tekkotsu Homepage
Demos
Overview
Downloads
Dev. Resources
Reference
Credits

FileSystemImageSource.cc

Go to the documentation of this file.
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 //better to put this here instead of the header
00008 using namespace std; 
00009 
00010 void FileSystemImageSource::ImageInfo::prepare() {
00011   if(prepared)
00012     return;
00013   if(data==NULL) {
00014     // load the file from disk
00015     FileInfo::prepare();
00016     if(data==NULL)
00017       return;
00018     
00019     // get the image info
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); // this call fails (no allocation), but sets image info
00024     size_t headerSize=getHeaderSize();
00025     totalSize = headerSize + width*height*components;
00026     // using mmap to allocate space so we can still use mlock/munlock on it later
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); // error, give up and clear our memory usage
00038       FileInfo::release();
00039       return;
00040     }
00041     
00042     // decompress the image for real this time:
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); // error, give up and clear our memory usage
00048       FileInfo::release();
00049       return; // don't fall through to the prepare() below!
00050     }
00051     
00052     // replace the raw compressed data with the uncompressed image
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 /*! @file
00075  * @brief 
00076  * @author Ethan Tira-Thompson (ejt) (Creator)
00077  *
00078  * $Author: ejt $
00079  * $Name: tekkotsu-4_0 $
00080  * $Revision: 1.2 $
00081  * $State: Exp $
00082  * $Date: 2007/06/22 18:33:52 $
00083  */

Tekkotsu Hardware Abstraction Layer 4.0
Generated Thu Nov 22 01:00:53 2007 by Doxygen 1.5.4