const unsigned char* FrameBuffer::GetPixels(unsigned channel, unsigned slice) const { ImgBuffer* img = FindImage(channel, slice); if (img) return img->GetPixels(); else return 0; }
bool ImgBuffer::Compatible(const ImgBuffer& img) const { if ( Height() != img.Height() || Width() != img.Width() || Depth() != img.Depth()) return false; return true; }
void ImgBuffer::Copy(const ImgBuffer& right) { if (!Compatible(right)) Resize(right.width_, right.height_, right.pixDepth_); SetPixels((void*)right.GetPixels()); }
int CoreCallback::InsertImage(const MM::Device* caller, const ImgBuffer & imgBuf) { Metadata md = imgBuf.GetMetadata(); unsigned char* p = const_cast<unsigned char*>(imgBuf.GetPixels()); MM::ImageProcessor* ip = GetImageProcessor(caller); if( NULL != ip) { ip->Process(p, imgBuf.Width(), imgBuf.Height(), imgBuf.Depth()); } return InsertImage(caller, imgBuf.GetPixels(), imgBuf.Width(), imgBuf.Height(), imgBuf.Depth(), &md); }
void COpenCVgrabber::GenerateEmptyImage(ImgBuffer& img) { MMThreadGuard g(imgPixelsLock_); if (img.Height() == 0 || img.Width() == 0 || img.Depth() == 0) return; unsigned char* pBuf = const_cast<unsigned char*>(img.GetPixels()); memset(pBuf, 0, img.Height()*img.Width()*img.Depth()); }
void CIDS_uEye::ClearImageBuffer(ImgBuffer& img) { MMThreadGuard g(imgPixelsLock_); if (img.Height() == 0 || img.Width() == 0 || img.Depth() == 0) return; unsigned char* pBuf = const_cast<unsigned char*>(img.GetPixels()); memset(pBuf, 0, img.Height()*img.Width()*img.Depth()); }
bool FrameBuffer::SetPixels(unsigned channel, unsigned slice, const unsigned char* pixels) { handlePending_ = false; ImgBuffer* img = FindImage(channel, slice); if (img) { // image already exists img->SetPixels(pixels); } else { // create a new buffer ImgBuffer* img = InsertNewImage(channel, slice); img->SetPixels(pixels); } return true; }
int SpotCamera::NextSequentialImage(ImgBuffer& img) { int nRet = DEVICE_OK; unsigned int bytesPerPixel; // e.g. 4 for RGB // values from the device unsigned int sourceheight, sourcewidth, sourcedepth; char cdepth; char *pData; pData = pImplementation_->GetNextSequentialImage( sourceheight, sourcewidth, cdepth ); sourcedepth = (int)cdepth; if (3 == sourcedepth) { bytesPerPixel = 4; } else { bytesPerPixel = (int)sourcedepth; } // EF: set the number of channels depending on the picture returned if ( cdepth < 3 ) { numberOfChannels_ = 1; } else { numberOfChannels_ = 4; } const unsigned long bytesRequired = sourceheight*sourcewidth*bytesPerPixel; if( (rawBufferSize_ < bytesRequired ) || (sourceheight != (unsigned int)img.Height()) || (sourcewidth != (unsigned int)img.Width()) || (bytesPerPixel !=img.Depth()) ) { this->ResizeImageBuffer( sourcewidth, sourceheight, bytesPerPixel); } unsigned int destdepth = img.Depth(); unsigned int destwidth = img.Width(); unsigned int destheight = img.Height(); //memset(ptemp, 0, destdepth*destwidth*destheight); // handle case where buffer doesn't match returned image size /* unsigned int xdest, ydest;//, xsource, ysource; int roffsetdest, goffsetdest, boffsetdest; int roffsetsource, goffsetsource, boffsetsource; unsigned int workingwidth = min(destwidth, sourcewidth); unsigned int workingheight = min(destheight, sourceheight); */ unsigned char* ptemp = img.GetPixelsRW(); memset(ptemp,0, destdepth*destwidth*destheight); // memcpy for all platforms now memcpy( ptemp, pData, destdepth*destwidth*destheight); /* Byte arrangement done in SpotDevice #ifndef WIN32 // __APPLE__ memcpy( ptemp, pData, destdepth*destwidth*destheight); #else #if 1 // no right left swap needed for( ydest = 0; ydest < workingheight; ++ydest) { for( xdest = 0; xdest < workingwidth; ++xdest) { roffsetdest = xdest*destdepth + destdepth*ydest*destwidth; goffsetdest = roffsetdest + 1; boffsetdest = goffsetdest + 1; roffsetsource = xdest*sourcedepth + sourcedepth*ydest*sourcewidth; goffsetsource = roffsetsource + 1; boffsetsource = goffsetsource + 1; ptemp[roffsetdest] = pData[roffsetsource]; if( 1 < destdepth) { ptemp[goffsetdest] = pData[goffsetsource]; ptemp[boffsetdest] = pData[boffsetsource]; } } } #endif #if 0 for( ydest = 0; ydest < workingheight; ++ydest) { for( int xsource = 0; xsource < workingwidth; ++xsource) { xdest = workingwidth - 1 - xsource; roffsetdest = xdest*destdepth + destdepth*ydest*destwidth; goffsetdest = roffsetdest + 1; boffsetdest = goffsetdest + 1; roffsetsource = xsource*sourcedepth + sourcedepth*ydest*sourcewidth; goffsetsource = roffsetsource + 1; boffsetsource = goffsetsource + 1; ptemp[roffsetdest] = pData[roffsetsource]; if( 1 < destdepth) { ptemp[goffsetdest] = pData[goffsetsource]; ptemp[boffsetdest] = pData[boffsetsource]; } } } #endif //img.SetPixels(ptemp); #endif */ return nRet; }
/** * Inserts a multi-channel frame in the buffer. */ bool CircularBuffer::InsertMultiChannel(const unsigned char* pixArray, unsigned numChannels, unsigned width, unsigned height, unsigned byteDepth, const Metadata* pMd) throw (CMMError) { MMThreadGuard guard(g_insertLock); static unsigned long previousTicks = 0; bool notOverflowed; ImgBuffer* pImg; unsigned long singleChannelSize = (unsigned long)width * height * byteDepth; { MMThreadGuard guard(g_bufferLock); if (previousTicks > 0) estimatedIntervalMs_ = GetClockTicksMs() - previousTicks; else estimatedIntervalMs_ = 0; // check image dimensions if (width != width_ || height != height_ || byteDepth != pixDepth_) throw CMMError("Incompatible image dimensions in the circular buffer", MMERR_CircularBufferIncompatibleImage); notOverflowed = (long)frameArray_.size() - (insertIndex_ - saveIndex_) > 0; if (!notOverflowed) { // buffer overflow overflow_ = true; return false; } } for (unsigned i=0; i<numChannels; i++) { Metadata md; { MMThreadGuard guard(g_bufferLock); // check if the requested (channel, slice) combination exists // we assume that all buffers are pre-allocated pImg = frameArray_[insertIndex_ % frameArray_.size()].FindImage(i, 0); if (!pImg) return false; if (pMd) { // TODO: the same metadata is inserted for each channel ??? // Perhaps we need to add specific tags to each channel md = *pMd; } std::string cameraName = md.GetSingleTag("Camera").GetValue(); if (imageNumbers_.end() == imageNumbers_.find(cameraName)) { imageNumbers_[cameraName] = 0; } // insert image number. md.put(MM::g_Keyword_Metadata_ImageNumber, CDeviceUtils::ConvertToString(imageNumbers_[cameraName])); ++imageNumbers_[cameraName]; } if (!md.HasTag(MM::g_Keyword_Elapsed_Time_ms)) { // if time tag was not supplied by the camera insert current timestamp MM::MMTime timestamp = GetMMTimeNow(); md.PutImageTag(MM::g_Keyword_Elapsed_Time_ms, CDeviceUtils::ConvertToString(timestamp.getMsec())); } md.PutImageTag("Width",width); md.PutImageTag("Height",height); if (byteDepth == 1) md.PutImageTag("PixelType","GRAY8"); else if (byteDepth == 2) md.PutImageTag("PixelType","GRAY16"); else if (byteDepth == 4) md.PutImageTag("PixelType","RGB32"); else if (byteDepth == 8) md.PutImageTag("PixelType","RGB64"); else md.PutImageTag("PixelType","Unknown"); pImg->SetMetadata(md); pImg->SetPixels(pixArray + i*singleChannelSize); } { MMThreadGuard guard(g_bufferLock); imageCounter_++; insertIndex_++; if ((insertIndex_ - (long)frameArray_.size()) > adjustThreshold && (saveIndex_- (long)frameArray_.size()) > adjustThreshold) { // adjust buffer indices to avoid overflowing integer size insertIndex_ -= adjustThreshold; saveIndex_ -= adjustThreshold; } } previousTicks = GetClockTicksMs(); return true; }