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; }
/** * 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; }