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 = 0;
00029 mThumbPrefix = "";
00030 String thumbSetDef = options.GetArg(2);
00031 if (FileNameExt(thumbSetDef) == ".txt")
00032 mThumbSet = MakeImageSet(thumbSetDef);
00033 else
00034 mThumbPrefix = thumbSetDef;
00035 mScale = 0.5;
00036 if (options.GetNrArg() > 3)
00037 mScale = atof(options.GetArg(3));
00038 mArchive = false;
00039 mSplitArchive = false;
00040 if (options.GetNrArg() > 4)
00041 {
00042 if (options.GetArg(4) == "archive")
00043 mArchive = true;
00044 if (options.GetArg(4) == "split")
00045 mSplitArchive = true;
00046 mReporter->SetReportArray(false);
00047 }
00048 mRkfMask = false;
00049 if (options.GetNrArg() > 5)
00050 {
00051 if (options.GetArg(5) == "rkf")
00052 mRkfMask = true;
00053 }
00054 mFirstImWidth = -1;
00055 mFirstImHeight = -1;
00056 mBufSize = 100000;
00057 mBuf = new char[mBufSize];
00058 if ((mArchive || mSplitArchive) && (!mThumbSet))
00059 {
00060 ILOG_ERROR("Archiving requires a thumbset");
00061 mArchive = false;
00062 mSplitArchive = false;
00063 }
00064 }
00065
00066 virtual
00067 ~Thumbnails()
00068 {
00069 delete mThumbSet;
00070 delete mBuf;
00071 }
00072
00073 virtual void
00074 HandleNewWalk(ImageSet* is)
00075 {
00076 if (mThumbSet && (is->NrFiles() != mThumbSet->NrFiles()))
00077 {
00078 ILOG_ERROR("Thumbnails: nr of files differs");
00079 }
00080 }
00081
00082 virtual void
00083 HandleNewFile(ImageSet* is, int fileId, Array::Array2dVec3UInt8* im)
00084 {
00085 ImType* blackIm = 0;
00086 if (!im)
00087 {
00088 ILOG_ERROR("No image");
00089 if (mFirstImWidth == -1)
00090 {
00091 ILOG_ERROR("No image size yet, so can't generate black image");
00092 return;
00093 }
00094 blackIm = Array::MakeFromValue<ImType>
00095 (Array::Element::Vec3Int32(0, 0, 0), mFirstImWidth,
00096 mFirstImHeight);
00097 im = blackIm;
00098 }
00099 if (mFirstImWidth == -1)
00100 {
00101 mFirstImWidth = im->CW();
00102 mFirstImHeight = im->CH();
00103 ILOG_INFO("First image has sizes : " << mFirstImWidth << " x "
00104 << mFirstImHeight);
00105 }
00106 if (mRkfMask)
00107 {
00108 String imFile = is->GetFile(fileId);
00109 if (imFile.find("_NRKF_") != String::npos)
00110 return;
00111 }
00112
00113 double scale = mScale;
00114 if (mScale > 1)
00115 {
00116 double scaleW = mScale / im->CW();
00117 double scaleH = mScale / im->CH();
00118 scale = Impala::Min(scaleW, scaleH);
00119 }
00120
00121 ImType* sc = 0;
00122 Array::Scale(sc, im, scale, scale, Geometry::NEAREST, true);
00123 if (mArchive || mSplitArchive)
00124 {
00125 String fName = (mThumbSet) ? mThumbSet->GetFile(fileId)
00126 : is->GetFile(fileId);
00127 size_t nrBytes = 0;
00128 if (FileNameExt(fName) == "jpg")
00129 Array::WriteJpgToMemory(sc, mBuf, mBufSize, &nrBytes);
00130 else
00131 Array::WritePngToMemory(sc, mBuf, mBufSize, &nrBytes);
00132 Array::Array2dScalarUInt8* bufIm =
00133 Array::MakeFromData<Array::Array2dScalarUInt8>((UInt8*) mBuf,
00134 nrBytes, 1);
00135 mImList.push_back(bufIm);
00136 }
00137 else
00138 {
00139 typedef Persistency::ImageLocator ImageLocator;
00140 if (mThumbSet)
00141 {
00142 ImageLocator loc = mThumbSet->GetImageLocator(fileId);
00143 Persistency::ImageRepository().Add(loc, sc);
00144 }
00145 else
00146 {
00147 String container = is->GetContainerDirOfFile(fileId);
00148 container = FileNameConcat(mThumbPrefix, container);
00149 ImageLocator loc = ImageLocator(is->GetLocator(), container,
00150 is->GetFile(fileId));
00151 Persistency::ImageRepository().Add(loc, sc);
00152 }
00153 }
00154 delete sc;
00155 if (blackIm)
00156 delete blackIm;
00157 }
00158
00159 virtual void
00160 HandleDoneDir(ImageSet* is, int dirId)
00161 {
00162 if (!mSplitArchive)
00163 return;
00164
00165 String container = mThumbSet->GetContainerDir(dirId);
00166 Persistency::ImageArchiveLocator loc(mThumbSet->GetLocator(), false,
00167 container, "images.raw", 0);
00168 Array::ImageArchiveMemory wrapper(&mImList);
00169 Persistency::ImageArchiveRepository().Add(loc, &wrapper);
00170 Array::ArrayListDelete(&mImList);
00171 }
00172
00173 virtual void
00174 HandleDoneWalk(ImageSet* is)
00175 {
00176 if (!mArchive)
00177 return;
00178
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 Array::ArrayListDelete(&mImList);
00185 }
00186
00187 private:
00188
00189 Reporter* mReporter;
00190 ImageSet* mThumbSet;
00191 String mThumbPrefix;
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