00001 #ifndef Impala_Core_ImageSet_Archive_h
00002 #define Impala_Core_ImageSet_Archive_h
00003
00004 #include "Core/ImageSet/Reporter.h"
00005 #include "Core/ImageSet/MakeImageSet.h"
00006 #include "Core/Array/MakeFromValue.h"
00007 #include "Core/Array/ArrayListDelete.h"
00008 #include "Core/Array/WriteRaw.h"
00009 #include "Core/Array/ImageArchiveMemory.h"
00010 #include "Core/Array/LimitCompressedImageSize.h"
00011
00012 namespace Impala
00013 {
00014 namespace Core
00015 {
00016 namespace ImageSet
00017 {
00018
00019
00020 class Archive : public Listener
00021 {
00022 typedef Array::Array2dScalarUInt8 CImType;
00023 typedef Array::Array2dVec3UInt8 RgbImType;
00024 public:
00025
00026 Archive(Reporter* reporter, CmdOptions& options)
00027 {
00028 mReporter = reporter;
00029 mReporter->SetReportArray(false);
00030 mSplit = false;
00031 if ((options.GetNrArg() > 2) && (options.GetArg(2) == "split"))
00032 mSplit = true;
00033 mMaxSize = -1;
00034 if (options.GetNrArg() > 3)
00035 mMaxSize = atol(options.GetArg(3));
00036 mMinSize = 64;
00037 if (options.GetNrArg() > 4)
00038 mMinSize = atol(options.GetArg(4));
00039 mNrBlackIm = 0;
00040 mNrSmallIm = 0;
00041 mNrBigIm = 0;
00042 }
00043
00044 virtual
00045 ~Archive()
00046 {
00047 Array::ArrayListDelete(&mImList);
00048 }
00049
00050 virtual void
00051 HandleNewFile(ImageSet* is, int fileId, Array::Array2dVec3UInt8* im)
00052 {
00053 if (im == 0)
00054 {
00055 ILOG_ERROR("No readable image, adding minSize black image");
00056 RgbImType* rgbIm = Array::MakeFromValue<RgbImType>(0, mMinSize,
00057 mMinSize);
00058 CompressAndAdd(rgbIm);
00059 mNrBlackIm++;
00060 return;
00061 }
00062
00063 if ((im->CW() < mMinSize) || (im->CH() < mMinSize))
00064 {
00065 ILOG_INFO("Image too small (" << im->CW() << "x" << im->CH() <<
00066 "), adding minSize black image");
00067 RgbImType* rgbIm = Array::MakeFromValue<RgbImType>(0, mMinSize,
00068 mMinSize);
00069 CompressAndAdd(rgbIm);
00070 mNrSmallIm++;
00071 return;
00072 }
00073
00074 if ((mMaxSize > 0) && ((im->CW() > mMaxSize) || (im->CH() > mMaxSize)))
00075 {
00076 double scale = 1.0;
00077 while ((scale*im->CW() > mMaxSize) || (scale*im->CH() > mMaxSize))
00078 scale *= 0.5;
00079
00080 RgbImType* sc = 0;
00081 Scale(sc, im, scale, scale, Core::Geometry::NEAREST, true);
00082 ILOG_INFO("Image too big, scaled it from " << im->CW() << "x" <<
00083 im->CH() << " to " << sc->CW() << "x" << sc->CH());
00084 CompressAndAdd(sc);
00085 mNrBigIm++;
00086 return;
00087 }
00088
00089
00090 CImType* bufIm = is->GetImageData(fileId);
00091 mImList.push_back(bufIm);
00092 }
00093
00094 virtual void
00095 HandleDoneDir(ImageSet* is, int dirId)
00096 {
00097 if (!mSplit)
00098 return;
00099
00100 String container = is->GetContainerDir(dirId);
00101 Persistency::ImageArchiveLocator loc(is->GetLocator(), false,
00102 container, "images.raw", 0);
00103
00104
00105
00106
00107 Array::ImageArchiveMemory wrapper(&mImList);
00108 Persistency::ImageArchiveRepository().Add(loc, &wrapper);
00109 Array::ArrayListDelete(&mImList);
00110 }
00111
00112 virtual void
00113 HandleDoneWalk(ImageSet* is)
00114 {
00115 ILOG_INFO("NrBlackIm=" << mNrBlackIm << ", NrSmallIm=" << mNrSmallIm
00116 << ", NrBigIm=" << mNrBigIm);
00117 if (mSplit)
00118 return;
00119
00120 String arName = is->GetSetNameBase() + ".raw";
00121 Persistency::ImageArchiveLocator loc(is->GetLocator(), false,
00122 "", arName, 0);
00123 Array::ImageArchiveMemory wrapper(&mImList);
00124 Persistency::ImageArchiveRepository().Add(loc, &wrapper);
00125 }
00126
00127 private:
00128
00129 void
00130 CompressAndAdd(RgbImType* im)
00131 {
00132 int charBufSize = im->CW() * im->CH() * 3 + 1024;
00133 char* charBuf = new char[charBufSize];
00134 size_t nrBytes;
00135 WritePngToMemory(im, charBuf, charBufSize, &nrBytes);
00136 delete im;
00137 CImType* bufIm = Array::MakeFromData<CImType>((UInt8*) charBuf,
00138 nrBytes, 1);
00139 delete charBuf;
00140 mImList.push_back(bufIm);
00141 }
00142
00143 Reporter* mReporter;
00144 bool mSplit;
00145 int mMaxSize;
00146 int mMinSize;
00147 std::vector<CImType*> mImList;
00148 int mNrBlackIm;
00149 int mNrSmallIm;
00150 int mNrBigIm;
00151
00152 ILOG_VAR_DEC;
00153 };
00154
00155 ILOG_VAR_INIT(Archive, Core.ImageSet);
00156
00157 }
00158 }
00159 }
00160
00161 #endif