bool SameType(const ImageBase& Img1, const ImageBase& Img2) { return (Img1.IsFloat() == Img2.IsFloat() && Img1.IsUnsigned() == Img2.IsUnsigned() && Img1.Depth() == Img2.Depth() && Img1.NbChannels() == Img2.NbChannels()); }
bool VectorProgram::IsImageFlush(const ImageBase& Source) { if (Source.Width() * Source.NbChannels() * Source.DepthBytes() != Source.Step()) return false; // Image has padding if ((Source.Width() * Source.NbChannels()) % GetVectorWidth(Source.DataType()) != 0) return false; // width is not a multiple of VectorWidth return true; }
static std::string SelectName(const char * Name, const ImageBase& Img) { if (Img.NbChannels() != 1) throw cl::Error(CL_IMAGE_FORMAT_NOT_SUPPORTED, "Filters on images with >1 channels not yet supported"); return std::string(Name) + "_1C"; }
void ImageProximityFFT::PrepareFor(ImageBase& Source, Image& Template) { SSize size; size.Width = Source.Width(); size.Height = Source.Height(); if (m_image_sqsums == nullptr || m_image_sqsums->Width() < size.Width || m_image_sqsums->Height() < size.Height) m_image_sqsums = std::make_shared<TempImage>(*m_CL, size, SImage::F32, Source.NbChannels()); // Size of the FFT input and output size.Width = Source.Width() + Template.Width() / 2; size.Height = Source.Height() + Template.Height() / 2; // Search for a size supported by clFFT while (!m_fft.IsSupportedLength(size.Width)) size.Width++; while (!m_fft.IsSupportedLength(size.Height)) size.Height++; if (m_bigger_source == nullptr || m_bigger_source->Width() != size.Width || m_bigger_source->Height() != size.Height) m_bigger_source = std::make_shared<TempImage>(*m_CL, size, SImage::F32, 1); if (m_bigger_template == nullptr || m_bigger_template->Width() < size.Width || m_bigger_template->Height() < size.Height) m_bigger_template = std::make_shared<TempImage>(*m_CL, size, SImage::F32, 1); // Size of the spectral images size.Width = size.Width / 2 + 1; if (m_templ_spect == nullptr || m_templ_spect->Width() < size.Width || m_templ_spect->Height() < size.Height) m_templ_spect = std::make_shared<TempImage>(*m_CL, size, SImage::F32, 2); if (m_source_spect == nullptr || m_source_spect->Width() != size.Width || m_source_spect->Height() != size.Height) m_source_spect = std::make_shared<TempImage>(*m_CL, size, SImage::F32, 2); if (m_result_spect == nullptr || m_result_spect->Width() < size.Width || m_result_spect->Height() < size.Height) m_result_spect = std::make_shared<TempImage>(*m_CL, size, SImage::F32, 2); m_integral.PrepareFor(Source); m_statistics.PrepareFor(Template); m_transform.PrepareFor(Source); m_fft.PrepareFor(*m_bigger_source, *m_source_spect); SelectProgram(Source).Build(); SelectProgram(*m_source_spect).Build(); }
cl::NDRange VectorProgram::GetRange(EProgramVersions Version, const ImageBase& Img1) { switch (Version) { case Fast: // The fast version uses a 1D range return cl::NDRange(Img1.Width() * Img1.Height() * Img1.NbChannels() / GetVectorWidth(Img1.DataType()), 1, 1); case Standard: case Unaligned: // The other versions use a 2D range return Img1.VectorRange(GetVectorWidth(Img1.DataType())); case NbVersions: default: throw cl::Error(CL_INVALID_PROGRAM, "Invalid program version in VectorProgram"); } }
void Check1Channel(const ImageBase& Img) { if (Img.NbChannels() > 1) throw cl::Error(CL_INVALID_VALUE, "only 1 channel images are allowed"); }
void CheckSameNbChannels(const ImageBase& Img1, const ImageBase& Img2) { if (Img1.NbChannels() != Img2.NbChannels()) throw cl::Error(CL_INVALID_VALUE, "Different number of channels used"); }
bool VectorProgram::IsImageAligned(const ImageBase& Source) { uint BytesPerWorker = Source.DepthBytes() * Source.NbChannels() * GetVectorWidth(Source.DataType()); return (Source.Step() % BytesPerWorker == 0); }