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