00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00033 #include <openvideo/nodes/ImageSrc.h>
00034 #include <openvideo/openVideo.h>
00035
00036 #ifdef ENABLE_IMAGESRC
00037
00038 #include <openvideo/Manager.h>
00039
00040 #ifdef OV_IS_WINXP
00041 # define SIMAGE_NOT_DLL
00042 # ifdef OV_IS_DEBUG
00043 # pragma message (">>> Linking against debug build of simage")
00044 # pragma comment(lib,"simagelibd.lib")
00045 # pragma message (">>> Linking against debug build of LibJPEG")
00046 # pragma comment(lib,"LibJPEGd.lib")
00047 # else
00048 # pragma message (">>> Linking against release build of simage")
00049 # pragma comment(lib,"simagelib.lib")
00050 # pragma message (">>> Linking against release build of LibJPEG")
00051 # pragma comment(lib,"LibJPEG.lib")
00052 # endif
00053 #else //WIN32
00054
00055 #endif
00056
00057 #include <openvideo/State.h>
00058 #include <ace/Time_Value.h>
00059 #include <ace/OS.h>
00060 #include <assert.h>
00061 #include <simage.h>
00062
00063
00064 namespace openvideo {
00065
00066
00067 static void
00068 flipImage(unsigned char* nSrc, unsigned char *nDst, int nStride, int nHeight)
00069 {
00070 nSrc += nStride*(nHeight-1);
00071
00072 for(int i=0; i<nHeight; i++)
00073 {
00074 memcpy(nDst, nSrc, nStride);
00075 nDst += nStride;
00076 nSrc -= nStride;
00077 }
00078 }
00079
00080 inline unsigned short
00081 convertPixel24To16(int nRed, int nGreen, int nBlue)
00082 {
00083 return (unsigned short)(((nRed << 8) & (0x1F << 11)) | ((nGreen << 3) & (0x3F << 5)) | (nBlue >> 3));
00084 }
00085
00086 static void
00087 convertRGB24toRGB565(unsigned short* nDestData, const unsigned char* nSrcData, int nNumPixels)
00088 {
00089 int i,j;
00090
00091 for(i=0,j=0; i<nNumPixels; i++,j+=3)
00092 nDestData[i] = convertPixel24To16(nSrcData[j+0], nSrcData[j+1], nSrcData[j+2]);
00093 }
00094
00095
00096
00097
00098 class ImageSrcBuffer : public Buffer
00099 {
00100 friend class ImageSrc;
00101 public:
00102 ImageSrcBuffer(unsigned char* pixels, State* state)
00103 {
00104 buffer = pixels;
00105 width = state->width;
00106 height = state->height;
00107 format = state->format;
00108 }
00109
00110 ~ImageSrcBuffer()
00111 {
00112 delete buffer;
00113 buffer = NULL;
00114 }
00115
00116 void setUpdateCtr(unsigned int ctr)
00117 {
00118 updateCtr = ctr;
00119 }
00120
00121 protected:
00122 };
00123
00124
00125
00126 class ImageSrcState : public State
00127 {
00128 public:
00129 ~ImageSrcState()
00130 {
00131 for(size_t i=0; i<buffers.size(); i++)
00132 delete buffers[i];
00133 buffers.clear();
00134 }
00135
00136 BufferVector& getBuffers() { return buffers; }
00137
00138 void setCurrentBuffer(Buffer* buf) { currentBuffer = buf; }
00139 };
00140
00141 #define IMAGE_State(_STATE) reinterpret_cast<ImageSrcState*>(_STATE)
00142
00143
00144 ImageSrc::ImageSrc()
00145 {
00146 numBuffers = 0;
00147 width = 320;
00148 height = 240;
00149 name = typeName = "ImageSrc";
00150 updateCtr = 1;
00151 curIdx = 0;
00152 delay = 1.0f;
00153 manual = true;
00154 doNextPic = true;
00155 lastUpdate = new ACE_Time_Value;
00156 }
00157
00158 ImageSrc::~ImageSrc()
00159 {
00160 state->unlockAllBuffers();
00161
00162
00163 delete state;
00164
00165 delete lastUpdate;
00166 }
00167
00168 void
00169 ImageSrc::initPixelFormats()
00170 {
00171 pixelFormats.push_back(PIXEL_FORMAT(FORMAT_R8G8B8));
00172 pixelFormats.push_back(PIXEL_FORMAT(FORMAT_R5G6B5));
00173 }
00174
00175
00176 void
00177 ImageSrc::init()
00178 {
00179 Manager::getInstance()->getLogger()->log("OpenVideo: start ImageSrc\n");
00180
00181
00182 state = new ImageSrcState();
00183 state->clear();
00184 state->format = curPixelFormat;
00185 state->width = width;
00186 state->height = height;
00187
00188 for(size_t i=0; i<fileNames.size(); i++)
00189 {
00190 int w=0,h=0,numC=0;
00191 unsigned char *buf2=0, *buf1=0, *buf0 = simage_read_image(fileNames[i].c_str(), &w,&h,&numC);
00192
00193 if(!buf0)
00194 {
00195 Manager::getInstance()->getLogger()->logEx("OpenVideo::ImageSrc: failed to load %s\n", fileNames[i].c_str());
00196 continue;
00197 }
00198
00199 if(numC!=3)
00200 {
00201 Manager::getInstance()->getLogger()->logEx("OpenVideo::ImageSrc: only images width 3 components supported, discarding %s\n", fileNames[i].c_str());
00202 simage_free_image(buf0);
00203 continue;
00204 }
00205
00206 assert(w);
00207 assert(h);
00208 assert(numC);
00209
00210 if(w!=width || h!=height)
00211 {
00212 buf1 = simage_resize(buf0, w,h,numC, width,height);
00213 simage_free_image(buf0);
00214 }
00215 else
00216 buf1 = buf0;
00217
00218 if(curPixelFormat==FORMAT_R5G6B5)
00219 {
00220 unsigned char *buf1a = new unsigned char[width*height*2];
00221 convertRGB24toRGB565(reinterpret_cast<unsigned short*>(buf1a), buf1, width*height);
00222 simage_free_image(buf1);
00223 buf2 = new unsigned char[width*height*2];
00224 flipImage(buf1a, buf2, width*2, height);
00225 delete buf1a;
00226 }
00227 else
00228 {
00229 buf2 = new unsigned char[width*height*3];
00230 flipImage(buf1, buf2, width*3, height);
00231 simage_free_image(buf1);
00232 }
00233
00234
00235
00236
00237
00238 IMAGE_State(state)->getBuffers().push_back(new ImageSrcBuffer(buf2, state));
00239 }
00240
00241
00242
00243 lastUpdate->set(0.0);
00244 }
00245
00246
00247 void
00248 ImageSrc::preProcess()
00249 {
00250 }
00251
00252
00253 void
00254 ImageSrc::process()
00255 {
00256 ACE_Time_Value currentTime = ACE_OS::gettimeofday(),
00257 dt = currentTime - *lastUpdate;
00258
00259 if((dt.msec() > 1000.0f*delay && !manual) || doNextPic)
00260 {
00261 if(++curIdx >= IMAGE_State(state)->getBuffers().size())
00262 curIdx = 0;
00263
00264 ImageSrcBuffer* buf = (ImageSrcBuffer*)IMAGE_State(state)->getBuffers()[curIdx];
00265 buf->setUpdateCtr(++updateCtr);
00266
00267 IMAGE_State(state)->setCurrentBuffer(buf);
00268
00269 *lastUpdate = currentTime;
00270 doNextPic = false;
00271 }
00272 }
00273
00274 void
00275 ImageSrc::postProcess()
00276 {
00277 }
00278
00279
00280 bool
00281 ImageSrc::setParameter(std::string key, std::string value)
00282 {
00283 if(Node::setParameter(key,value))
00284 return true;
00285
00286 if(key=="width")
00287 {
00288 width = atoi(value.c_str());
00289 return true;
00290 }
00291
00292 if(key=="height")
00293 {
00294 height = atoi(value.c_str());
00295 return true;
00296 }
00297
00298 if(key=="delay")
00299 {
00300 if(value=="manual")
00301 manual = true;
00302 else
00303 {
00304 delay = (float)atof(value.c_str());
00305 manual = false;
00306 }
00307 return true;
00308 }
00309
00310 if(key.substr(0, 5)=="image")
00311 {
00312 fileNames.push_back(value);
00313 }
00314
00315 return false;
00316 }
00317
00318
00319 }
00320
00321
00322 #endif //ENABLE_IMAGESRC