00001 #ifndef Impala_Core_VideoSet_ExportKeyframes_h
00002 #define Impala_Core_VideoSet_ExportKeyframes_h
00003
00004 #include "Persistency/ImageArchiveRepository.h"
00005 #include "Persistency/FrameRepository.h"
00006 #include "Core/Array/ImageArchiveMemory.h"
00007 #include "Basis/FileName.h"
00008 #include "Core/Array/WriteJpg.h"
00009 #include "Core/Array/WritePng.h"
00010 #include "Core/Array/WriteRaw.h"
00011 #include "Core/Array/Scale.h"
00012 #include "Core/Array/ArrayListDelete.h"
00013 #include "Core/VideoSet/Reporter.h"
00014 #include "Core/VideoSet/Keyframes.h"
00015 #include "Core/ImageSet/MakeImageSet.h"
00016
00017 namespace Impala
00018 {
00019 namespace Core
00020 {
00021 namespace VideoSet
00022 {
00023
00024
00025 class ExportKeyframes : public Listener
00026 {
00027 public:
00028
00029 ExportKeyframes(Reporter* reporter, CmdOptions& options, VideoSet* vs)
00030 {
00031 mReporter = reporter;
00032 mKeyframes = 0;
00033 if (options.GetNrArg() < 6)
00034 {
00035 ILOG_ERROR("Missing argument");
00036 return;
00037 }
00038
00039
00040 #ifndef REPOSITORY_USED // Here comes the deprecated stuff
00041 mImSet = Core::ImageSet::MakeImageSet(options.GetArg(2),
00042 vs->GetDatabase());
00043 #else // REPOSITORY_USED
00044 mImSet = Core::ImageSet::MakeImageSet(options.GetArg(2));
00045 #endif // REPOSITORY_USED
00046 if (!mImSet)
00047 {
00048 ILOG_ERROR("Image set was not constructed");
00049 return;
00050 }
00051
00052 mScale = atof(options.GetArg(3));
00053
00054 mArchive = false;
00055 mSplitArchive = false;
00056 if (options.GetArg(4) == "archive")
00057 mArchive = true;
00058 else if (options.GetArg(4) == "split")
00059 mSplitArchive = true;
00060 else if (options.GetArg(4) != "file")
00061 ILOG_ERROR("arg 4 should be file|archive|split");
00062
00063 mForcePng = false;
00064 if (options.GetArg(5) == "png")
00065 mForcePng = true;
00066 else if (options.GetArg(5) != "jpg")
00067 ILOG_ERROR("arg 5 should be jpg|png");
00068
00069 if (options.GetNrArg() > 6)
00070 Core::Array::gWriteJpgQuality = atol(options.GetArg(6));
00071
00072 mBuf = 0;
00073 if (mArchive || mSplitArchive)
00074 {
00075 mBufSize = 10000000;
00076 mBuf = new char[mBufSize];
00077 mReporter->SetReportArray(false);
00078 }
00079 }
00080
00081 virtual
00082 ~ExportKeyframes()
00083 {
00084 if (mBuf)
00085 delete mBuf;
00086 }
00087
00088 virtual void
00089 HandleNewWalk(VideoSet* vs, Keyframes* keyframes, bool* keyframeMask)
00090 {
00091 mKeyframes = keyframes;
00092 mCurKey = 0;
00093 #ifndef REPOSITORY_USED // Here comes the deprecated stuff
00094 mImSet->SetDatabase(vs->GetDatabase());
00095 #endif // REPOSITORY_USED
00096 }
00097
00098 virtual void
00099 HandleNewFile(VideoSet* vs, int fileId, Stream::RgbDataSrc* src)
00100 {
00101 mCurKey = mKeyframes->GetFirstKeyframeVideo(fileId);
00102 }
00103
00104 virtual void
00105 HandleNewFrame(VideoSet* vs, int fileId, Stream::RgbDataSrc* src)
00106 {
00107 if ((mKeyframes->Get1(mCurKey) != fileId) ||
00108 (mKeyframes->Get3(mCurKey) != src->FrameNr()))
00109 {
00110 if (mKeyframes->Get1(mCurKey) != fileId)
00111 ILOG_ERROR("Wrong video: " << fileId << " instead of "
00112 << mKeyframes->Get1(mCurKey));
00113 if (mKeyframes->Get3(mCurKey) != src->FrameNr())
00114 ILOG_ERROR("Wrong frame: " << src->FrameNr() << " instead of "
00115 << mKeyframes->Get3(mCurKey) << " for keyId "
00116 << mCurKey);
00117
00118
00119 }
00120 typedef Array::Array2dVec3UInt8 ArrayT;
00121 ArrayT* im = Array::ArrayCreate<ArrayT>
00122 (src->FrameWidth(), src->FrameHeight(), 0, 0, src->DataPtr(), true);
00123 ArrayT* sc = 0;
00124 if (mScale == 1.0)
00125 sc = im;
00126 else
00127 Array::Scale(sc, im, mScale, mScale, Geometry::NEAREST, true);
00128 if (mArchive || mSplitArchive)
00129 {
00130 size_t nrBytes = 0;
00131 String ext = FileNameExt(mImSet->GetFile(mCurKey));
00132 if ((ext == "png") || (mForcePng))
00133 Array::WritePngToMemory(sc, mBuf, mBufSize, &nrBytes);
00134 else
00135 Array::WriteJpgToMemory(sc, mBuf, mBufSize, &nrBytes);
00136 Array::Array2dScalarUInt8* data =
00137 Array::MakeFromData<Array::Array2dScalarUInt8>((UInt8*) mBuf,
00138 nrBytes, 1);
00139 mImList.push_back(data);
00140 }
00141 else
00142 {
00143 #ifndef REPOSITORY_USED // Here comes the deprecated stuff
00144 String fName = mImSet->GetFilePathImageData(mCurKey, true, false);
00145 if (mForcePng)
00146 fName = StringReplace(fName, ".jpg", ".png");
00147 if (fName.empty())
00148 {
00149 ILOG_ERROR("Empty filename");
00150 }
00151 else
00152 {
00153 if (FileNameExt(fName, true) == "jpg")
00154 Array::WriteJpg(sc, fName, mImSet->GetDatabase());
00155 else
00156 Array::WritePng(sc, fName, mImSet->GetDatabase());
00157 }
00158 #else // REPOSITORY_USED
00159 String container = mImSet->GetContainerDirOfFile(mCurKey);
00160 String fName = mImSet->GetFile(mCurKey);
00161 if (mForcePng)
00162 fName = StringReplace(fName, ".jpg", ".png");
00163 Persistency::ImageLocator loc(vs->GetLocator(), container, fName);
00164 Persistency::ImageRepository().Add(loc, sc);
00165 #endif // REPOSITORY_USED
00166 }
00167 if (sc != im)
00168 delete sc;
00169 delete im;
00170 mCurKey++;
00171 }
00172
00173 virtual void
00174 HandleDoneFile(VideoSet* vs, int fileId, Stream::RgbDataSrc* src)
00175 {
00176 if (!mSplitArchive)
00177 return;
00178 #ifndef REPOSITORY_USED // Here comes the deprecated stuff
00179 int id = mImSet->GetFirstFileId(fileId);
00180 String fName = mImSet->GetFilePathImageArchive(id, "images.raw",
00181 true, false);
00182 if (fName.empty())
00183 return;
00184 Array::WriteRawListVar(mImList, fName, mImSet->GetDatabase(), true, true);
00185 #else // REPOSITORY_USED
00186 String container = mImSet->GetContainerDir(fileId);
00187 Persistency::ImageArchiveLocator loc(vs->GetLocator(), false,
00188 container, "images.raw", 0);
00189 Array::ImageArchiveMemory wrapper(&mImList);
00190 Persistency::ImageArchiveRepository().Add(loc, &wrapper);
00191 #endif // REPOSITORY_USED
00192 Array::ArrayListDelete(&mImList);
00193 }
00194
00195 virtual void
00196 HandleDoneWalk(VideoSet* vs)
00197 {
00198 if (!mArchive)
00199 return;
00200 String fName = mImSet->GetSetNameBase() + ".raw";
00201 #ifndef REPOSITORY_USED // Here comes the deprecated stuff
00202 fName = mImSet->GetFilePathImageArchive(fName, true, false);
00203 if (fName.empty())
00204 return;
00205 ILOG_INFO("writing archive [" << fName << "]");
00206 Array::WriteRawListVar(mImList, fName, mImSet->GetDatabase(), true,
00207 true);
00208 #else // REPOSITORY_USED
00209 Persistency::ImageArchiveLocator loc(vs->GetLocator(), false,
00210 "", fName, 0);
00211 Array::ImageArchiveMemory wrapper(&mImList);
00212 Persistency::ImageArchiveRepository().Add(loc, &wrapper);
00213 #endif // REPOSITORY_USED
00214 Array::ArrayListDelete(&mImList);
00215 }
00216
00217 private:
00218
00219 Reporter* mReporter;
00220 Keyframes* mKeyframes;
00221 ImageSet::ImageSet* mImSet;
00222 int mCurKey;
00223 bool mArchive;
00224 bool mSplitArchive;
00225 bool mForcePng;
00226 double mScale;
00227 int mBufSize;
00228 char* mBuf;
00229 std::vector<Array::Array2dScalarUInt8*> mImList;
00230
00231 ILOG_VAR_DEC;
00232
00233 };
00234
00235 ILOG_VAR_INIT(ExportKeyframes, Impala.Core.VideoSet);
00236
00237 }
00238 }
00239 }
00240
00241 #endif