00001 #ifndef Impala_Core_ImageSet_Thumbnails_h
00002 #define Impala_Core_ImageSet_Thumbnails_h
00003
00004 #include "Core/ImageSet/Reporter.h"
00005 #include "Core/ImageSet/MakeImageSet.h"
00006 #include "Core/Array/MakeFromValue.h"
00007 #include "Core/Array/Scale.h"
00008 #include "Core/Array/WriteJpg.h"
00009 #include "Core/Array/WritePng.h"
00010 #include "Core/Array/ImageArchiveMemory.h"
00011
00012 namespace Impala
00013 {
00014 namespace Core
00015 {
00016 namespace ImageSet
00017 {
00018
00019
00020 class Thumbnails : public Listener
00021 {
00022 typedef Array::Array2dVec3UInt8 ImType;
00023 public:
00024
00025 Thumbnails(Reporter* reporter, CmdOptions& options)
00026 {
00027 mReporter = reporter;
00028 mThumbSet = MakeImageSet(options.GetArg(2));
00029 mScale = 0.5;
00030 if (options.GetNrArg() > 3)
00031 mScale = atof(options.GetArg(3));
00032 mArchive = false;
00033 mSplitArchive = false;
00034 if (options.GetNrArg() > 4)
00035 {
00036 if (options.GetArg(4) == "archive")
00037 mArchive = true;
00038 if (options.GetArg(4) == "split")
00039 mSplitArchive = true;
00040 mReporter->SetReportArray(false);
00041 }
00042 mRkfMask = false;
00043 if (options.GetNrArg() > 5)
00044 {
00045 if (options.GetArg(5) == "rkf")
00046 mRkfMask = true;
00047 }
00048 mFirstImWidth = -1;
00049 mFirstImHeight = -1;
00050 mBufSize = 100000;
00051 mBuf = new char[mBufSize];
00052 }
00053
00054 virtual
00055 ~Thumbnails()
00056 {
00057 delete mThumbSet;
00058 delete mBuf;
00059 }
00060
00061 virtual void
00062 HandleNewWalk(ImageSet* is)
00063 {
00064 if (is->NrFiles() != mThumbSet->NrFiles())
00065 {
00066 ILOG_ERROR("Thumbnails: nr of files differs");
00067 }
00068 }
00069
00071 virtual void
00072 HandleNewFile(ImageSet* is, int fileId, Array::Array2dVec3UInt8* im)
00073 {
00074 ImType* blackIm = 0;
00075 if (!im)
00076 {
00077 ILOG_ERROR("No image");
00078 if (mFirstImWidth == -1)
00079 {
00080 ILOG_ERROR("No image size yet, so can't generate black image");
00081 return;
00082 }
00083 blackIm = Array::MakeFromValue<ImType>
00084 (Array::Element::Vec3Int32(0, 0, 0), mFirstImWidth,
00085 mFirstImHeight);
00086 im = blackIm;
00087 }
00088 if (mFirstImWidth == -1)
00089 {
00090 mFirstImWidth = im->CW();
00091 mFirstImHeight = im->CH();
00092 ILOG_INFO("First image has sizes : " << mFirstImWidth << " x "
00093 << mFirstImHeight);
00094 }
00095 if (mRkfMask)
00096 {
00097 String imFile = is->GetFile(fileId);
00098 if (imFile.find("_NRKF_") != String::npos)
00099 return;
00100 }
00101 ImType* sc = 0;
00102 Array::Scale(sc, im, mScale, mScale, Geometry::NEAREST, true);
00103 if (mArchive || mSplitArchive)
00104 {
00105 size_t nrBytes = 0;
00106 if (FileNameExt(mThumbSet->GetFile(fileId)) == "jpg")
00107 Array::WriteJpgToMemory(sc, mBuf, mBufSize, &nrBytes);
00108 else
00109 Array::WritePngToMemory(sc, mBuf, mBufSize, &nrBytes);
00110 Array::Array2dScalarUInt8* bufIm =
00111 Array::MakeFromData<Array::Array2dScalarUInt8>((UInt8*) mBuf,
00112 nrBytes, 1);
00113 mImList.push_back(bufIm);
00114 }
00115 else
00116 {
00117 #ifndef REPOSITORY_USED // Here comes the deprecated stuff
00118 String resFile = mThumbSet->GetFilePathImageData(fileId, true,
00119 false);
00120 Array::WriteJpg(sc, resFile, mThumbSet->GetDatabase());
00121 #else // REPOSITORY_USED
00122 String container = mThumbSet->GetContainerDirOfFile(fileId);
00123 Persistency::ImageLocator loc(mThumbSet->GetLocator(), container,
00124 mThumbSet->GetFile(fileId));
00125 Persistency::ImageRepository().Add(loc, sc);
00126 #endif // REPOSITORY_USED
00127 }
00128 delete sc;
00129 if (blackIm)
00130 delete blackIm;
00131 }
00132
00133 virtual void
00134 HandleDoneDir(ImageSet* is, int dirId)
00135 {
00136 if (!mSplitArchive)
00137 return;
00138 #ifndef REPOSITORY_USED // Here comes the deprecated stuff
00139 int fileId = mThumbSet->GetFirstFileId(dirId);
00140 String fName = mThumbSet->GetFilePathImageArchive(fileId, "images.raw",
00141 true, false);
00142 if (!fName.empty())
00143 {
00144 Array::WriteRawListVar(mImList, fName, mThumbSet->GetDatabase(),
00145 true, true);
00146 }
00147 else
00148 {
00149 ILOG_ERROR("Unable to write split archive");
00150 }
00151 #else // REPOSITORY_USED
00152 String container = mThumbSet->GetContainerDir(dirId);
00153 Persistency::ImageArchiveLocator loc(mThumbSet->GetLocator(), false,
00154 container, "images.raw", 0);
00155 Array::ImageArchiveMemory wrapper(&mImList);
00156 Persistency::ImageArchiveRepository().Add(loc, &wrapper);
00157 #endif // REPOSITORY_USED
00158 Array::ArrayListDelete(&mImList);
00159 }
00160
00161 virtual void
00162 HandleDoneWalk(ImageSet* is)
00163 {
00164 if (!mArchive)
00165 return;
00166
00167 #ifndef REPOSITORY_USED // Here comes the deprecated stuff
00168 String fName = mThumbSet->GetSetNameBase() + ".raw";
00169 fName = mThumbSet->GetFilePathImageArchive(fName, true, false);
00170 if (fName.empty())
00171 {
00172 ILOG_ERROR("Thumbnails: Couldn't write archive");
00173 return;
00174 }
00175 ILOG_INFO("writing archive [" << fName << "]");
00176 Array::WriteRawListVar(mImList, fName, mThumbSet->GetDatabase(), true,
00177 true);
00178 #else // REPOSITORY_USED
00179 String arName = mThumbSet->GetSetNameBase() + ".raw";
00180 Persistency::ImageArchiveLocator loc(mThumbSet->GetLocator(), false,
00181 "", arName, 0);
00182 Array::ImageArchiveMemory wrapper(&mImList);
00183 Persistency::ImageArchiveRepository().Add(loc, &wrapper);
00184 #endif // REPOSITORY_USED
00185 Array::ArrayListDelete(&mImList);
00186 }
00187
00188 private:
00189
00190 Reporter* mReporter;
00191 ImageSet* mThumbSet;
00192 double mScale;
00193 bool mArchive;
00194 bool mSplitArchive;
00195 bool mRkfMask;
00196 int mFirstImWidth;
00197 int mFirstImHeight;
00198 int mBufSize;
00199 char* mBuf;
00200 std::vector<Array::Array2dScalarUInt8*> mImList;
00201
00202 ILOG_VAR_DEC;
00203 };
00204
00205 ILOG_VAR_INIT(Thumbnails, Impala.Core.ImageSet);
00206
00207 }
00208 }
00209 }
00210
00211 #endif