00001 #ifndef Impala_Core_Array_ImageArchiveFile_h
00002 #define Impala_Core_Array_ImageArchiveFile_h
00003
00004 #include "Persistency/File.h"
00005 #include "Core/Array/ImageArchive.h"
00006 #include "Util/DatabaseWriteNative.h"
00007 #include "Util/DatabaseReadNative.h"
00008 #include "Core/Array/ReadRaw.h"
00009 #include "Core/Array/WriteRaw.h"
00010 #include "Core/Array/ReadImage.h"
00011
00012 namespace Impala
00013 {
00014 namespace Core
00015 {
00016 namespace Array
00017 {
00018
00019
00020 class ImageArchiveFile : public ImageArchive
00021 {
00022 public:
00023
00024 #ifndef REPOSITORY_USED // Here comes the deprecated stuff
00025 ImageArchiveFile(CString fName, bool useMemory, Util::Database* db)
00026 {
00027 Init(fName, useMemory, db);
00028 }
00029 #endif // REPOSITORY_USED
00030
00031 ImageArchiveFile(Persistency::File file)
00032 {
00033 mIOBuffer = 0;
00034 if (!file.Valid())
00035 {
00036 ILOG_ERROR("Invalid file");
00037 return;
00038 }
00039
00040 mIOBuffer = file.GetReadBuffer();
00041 if (!mIOBuffer)
00042 return;
00043
00044 Persistency::File idxFile(file.GetPath() + ".idx", file.GetFileSystem(),
00045 file.IsWritable());
00046 idxFile.ReadNative(std::back_inserter(mFileOffset), true);
00047 if (mFileOffset.size() == 0)
00048 ILOG_ERROR("Empty .idx file");
00049 }
00050
00051 virtual
00052 ~ImageArchiveFile()
00053 {
00054 if (mIOBuffer)
00055 delete mIOBuffer;
00056 }
00057
00058 bool
00059 Valid()
00060 {
00061 return (mIOBuffer != 0) && (mFileOffset.size() != 0);
00062 }
00063
00064 int
00065 NrImages()
00066 {
00067 return mFileOffset.size();
00068 }
00069
00070 Array2dVec3UInt8*
00071 ReadImage(int idx)
00072 {
00073 if (!Valid())
00074 {
00075 ILOG_ERROR("Cannot ReadImage: archive not valid");
00076 return 0;
00077 }
00078
00079 size_t blockSize = 0;
00080 UInt8* data = GetImageData(idx, blockSize);
00081 Array2dVec3UInt8* im = 0;
00082 ReadImageFromMemory(im, (char*) data, blockSize);
00083 delete data;
00084 return im;
00085 }
00086
00087 UInt8*
00088 GetImageData(int idx, size_t& blockSize)
00089 {
00090 if (!Valid())
00091 {
00092 ILOG_ERROR("Cannot GetImageData: archive not valid");
00093 return 0;
00094 }
00095 if (idx >= mFileOffset.size())
00096 {
00097 ILOG_ERROR("Index out of bounds: " << idx << " vs. " <<
00098 mFileOffset.size());
00099 return 0;
00100 }
00101
00102 mIOBuffer->SetPosition(mFileOffset[idx]);
00103 char buf[200];
00104 int width;
00105 int height;
00106 mIOBuffer->Read(buf, 20);
00107 sscanf(buf, "%d %d ", &width, &height);
00108 blockSize = width*height;
00109 UInt8* data = new UInt8[blockSize];
00110 size_t nrRead = mIOBuffer->Read(data, blockSize);
00111 if (nrRead != blockSize)
00112 ILOG_ERROR("GetImageData: read " << nrRead
00113 << " bytes instead of " << blockSize);
00114 return data;
00115 }
00116
00117 private:
00118
00119 #ifndef REPOSITORY_USED // Here comes the deprecated stuff
00120 void
00121 Init(CString fileName, bool useMemory, Util::Database* db)
00122 {
00123 mIOBuffer = 0;
00124
00125 if (db == 0)
00126 {
00127 ILOG_ERROR("No database given");
00128 return;
00129 }
00130 if (fileName.empty())
00131 {
00132 ILOG_ERROR("Empty fileName");
00133 return;
00134 }
00135
00136
00137 mIOBuffer = db->GetIOBuffer(fileName, true, useMemory, "", 0, true);
00138
00139 if (!mIOBuffer)
00140 return;
00141
00142 const String idxPath = fileName + ".idx";
00143 if (CmdOptions::GetInstance().GetString("dataServer").empty())
00144 {
00145
00146
00147
00148 if (!Util::IOBufferFile::FileExists(idxPath))
00149 {
00150 ReadRawListVarIndex<Array2dScalarUInt8>(mFileOffset, mIOBuffer);
00151 ILOG_INFO("saving index [" + idxPath + "]");
00152 Util::DatabaseWriteNative(idxPath, db, mFileOffset.begin(),
00153 mFileOffset.end());
00154 return;
00155 }
00156 }
00157
00158 Util::IOBuffer* indexBuffer = db->GetIOBuffer(idxPath, true, true, "");
00159 Util::DatabaseReadNative(std::back_inserter(mFileOffset), indexBuffer);
00160 delete indexBuffer;
00161 if (mFileOffset.size() == 0)
00162 ILOG_ERROR("Empty .idx file");
00163 }
00164 #endif // REPOSITORY_USED
00165
00166 Util::IOBuffer* mIOBuffer;
00167 std::vector<Int64> mFileOffset;
00168
00169 ILOG_VAR_DEC;
00170 };
00171
00172 ILOG_VAR_INIT(ImageArchiveFile, Impala.Core.Array);
00173
00174 }
00175 }
00176 }
00177
00178 #endif