bool ImageBufAlgo::render_line (ImageBuf &dst, int x1, int y1, int x2, int y2, array_view<const float> color, bool skip_first_point, ROI roi, int nthreads) { if (! IBAprep (roi, &dst)) return false; if (int(color.size()) < roi.chend) { dst.error ("Not enough channels for the color (needed %d)", roi.chend); return false; // Not enough color channels specified } const ImageSpec &spec (dst.spec()); // Alpha: if the image's spec designates an alpha channel, use it if // it's within the range specified by color. Otherwise, if color // includes more values than the highest channel roi says we should // modify, assume the first extra value is alpha. If all else fails, // make the line opaque (alpha=1.0). float alpha = 1.0f; if (spec.alpha_channel >= 0 && spec.alpha_channel < int(color.size())) alpha = color[spec.alpha_channel]; else if (int(color.size()) == roi.chend+1) alpha = color[roi.chend]; bool ok; OIIO_DISPATCH_TYPES (ok, "render_line", render_line_, dst.spec().format, dst, x1, y1, x2, y2, color, alpha, skip_first_point, roi, nthreads); return ok; }
static bool render_box_ (ImageBuf &dst, array_view<const float> color, ROI roi=ROI(), int nthreads=1) { if (nthreads != 1 && roi.npixels() >= 1000) { // Lots of pixels and request for multi threads? Parallelize. ImageBufAlgo::parallel_image ( OIIO::bind(render_box_<T>, OIIO::ref(dst), color, _1 /*roi*/, 1 /*nthreads*/), roi, nthreads); return true; } // Serial case float alpha = 1.0f; if (dst.spec().alpha_channel >= 0 && dst.spec().alpha_channel < int(color.size())) alpha = color[dst.spec().alpha_channel]; else if (int(color.size()) == roi.chend+1) alpha = color[roi.chend]; if (alpha == 1.0f) { for (ImageBuf::Iterator<T> r (dst, roi); !r.done(); ++r) for (int c = roi.chbegin; c < roi.chend; ++c) r[c] = color[c]; } else { for (ImageBuf::Iterator<T> r (dst, roi); !r.done(); ++r) for (int c = roi.chbegin; c < roi.chend; ++c) r[c] = color[c] + r[c] * (1.0f-alpha); // "over" } return true; }
void ClipFacade::SetFeatureMatrix(array_view<ArmatureFrame> frames, double duration, bool cyclic) { assert(m_pParts != nullptr && m_flag != NotInitialize); m_inited = false; auto& parts = *m_pParts; int fLength = m_partDim.back() + m_partSt.back(); auto dt = duration / (frames.size() - (size_t)(!cyclic)); bool useVelocity = dt > 0; m_X.resize(frames.size(), fLength); for (int f = 0; f < frames.size(); f++) { auto& lastFrame = frames[f>0?f-1:frames.size()-1]; auto& frame = frames[f]; for (int i = 0; i < parts.size(); i++) { auto part = parts[i]; auto fv = m_X.block(f, m_partSt[i], 1, m_partDim[i]); if (!useVelocity) fv = m_pFeature->Get(*part, frame); else fv = m_pFeature->Get(*part, frame, lastFrame, dt); } } }
std::unique_ptr<uint8_t[]> DecodeTga(array_view<uint8_t> data) { if (data.size() < sizeof(TgaHeader)) { throw TempleException("Not enough data for TGA header"); } auto header = reinterpret_cast<const TgaHeader*>(data.data()); if (header->colorMapType != TgaColorMapType::TrueColor) { throw TempleException("Only true color TGA images are supported."); } if (header->dataType != TgaDataType::UncompressedRgb) { throw TempleException("Only uncompressed RGB TGA images are supported."); } if (header->bpp != 24 && header->bpp != 32) { throw TempleException("Only uncompressed RGB 24-bpp or 32-bpp TGA images are supported."); } auto result(std::make_unique<uint8_t[]>(header->width * header->height * 4)); auto dest = result.get(); // Points to the start of the TGA image data auto srcStart = data.data() + sizeof(TgaHeader) + header->imageIdLength; auto srcSize = data.size() - sizeof(TgaHeader) - header->imageIdLength; if (header->bpp == 24) { auto srcPitch = header->width * 3; Expects((int) srcSize >= header->height * srcPitch); for (int y = 0; y < header->height; ++y) { auto src = srcStart + (header->height - y - 1) * srcPitch; for (int x = 0; x < header->width; ++x) { *dest++ = *src++; *dest++ = *src++; *dest++ = *src++; *dest++ = 0xFF; // Fixed alpha } } } else { auto srcPitch = header->width * 4; Expects((int) srcSize >= header->height * srcPitch); for (int y = 0; y < header->height; ++y) { auto src = srcStart + (header->height - y - 1) * srcPitch; for (int x = 0; x < header->width; ++x) { *dest++ = *src++; *dest++ = *src++; *dest++ = *src++; *dest++ = *src++; } } } return result; }
bool ImageBufAlgo::render_box (ImageBuf &dst, int x1, int y1, int x2, int y2, array_view<const float> color, bool fill, ROI roi, int nthreads) { if (! IBAprep (roi, &dst)) return false; if (int(color.size()) < roi.chend) { dst.error ("Not enough channels for the color (needed %d)", roi.chend); return false; // Not enough color channels specified } // Filled case if (fill) { roi = roi_intersection (roi, ROI(x1, x2+1, y1, y2+1, 0, 1, 0, roi.chend)); bool ok; OIIO_DISPATCH_TYPES (ok, "render_box", render_box_, dst.spec().format, dst, color, roi, nthreads); return ok; } // Unfilled case: use IBA::render_line return ImageBufAlgo::render_line (dst, x1, y1, x2, y1, color,true, roi, nthreads) && ImageBufAlgo::render_line (dst, x2, y1, x2, y2, color,true, roi, nthreads) && ImageBufAlgo::render_line (dst, x2, y2, x1, y2, color,true, roi, nthreads) && ImageBufAlgo::render_line (dst, x1, y2, x1, y1, color,true, roi, nthreads); }
bool DetectTga(array_view<uint8_t> data, ImageFileInfo& info) { if (data.size() < sizeof(TgaHeader)) { return false; } auto header = reinterpret_cast<const TgaHeader*>(data.data()); if (header->colorMapType != TgaColorMapType::TrueColor) { return false; // We don't supported index TGA } if (header->dataType != TgaDataType::UncompressedRgb) { return false; // We only support uncompressed RGB } if (header->bpp != 24 && header->bpp != 32) { return false; // We only support 24 or 32 bit TGAs } info.width = header->width; info.height = header->height; info.hasAlpha = (header->bpp == 32); info.format = ImageFileFormat::TGA; return true; }
ImageFileInfo DetectImageFormat(array_view<uint8_t> data) { ImageFileInfo info; stbi__context ctx; stbi__start_mem(&ctx, &data[0], data.bytes()); int comp; if (stbi__bmp_info(&ctx, &info.width, &info.height, &comp)) { info.hasAlpha = (comp == 4); info.format = ImageFileFormat::BMP; return info; } TjDecompressHandle handle; if (tjDecompressHeader(handle, &data[0], data.bytes(), &info.width, &info.height) == 0) { info.hasAlpha = false; info.format = ImageFileFormat::JPEG; return info; } if (DetectTga(data, info)) { return info; } // Not a very good heuristic if (data.size() == 256 * 256) { info.width = 256; info.height = 256; info.hasAlpha = true; info.format = ImageFileFormat::FNTART; return info; } return info; }
void AbsoluteLnQuaternionDecoder::Decode(array_view<DirectX::Quaternion> rots, const VectorType & x) { int n = rots.size(); Eigen::Vector4f qs; XMVECTOR q; qs.setZero(); for (int i = 0; i < n; i++) { qs.segment<3>(0) = x.segment<3>(i * 3).cast<float>(); q = XMLoadFloat4A(qs.data()); q = XMQuaternionExp(q); // revert the log map XMStoreA(rots[i], q); } }
void AbsoluteEulerAngleDecoder::Decode(array_view<DirectX::Quaternion> rots, const VectorType & y) { int n = rots.size(); Eigen::Vector4f qs; XMVECTOR q; qs.setZero(); for (int i = 0; i < n; i++) { qs.segment<3>(0) = y.segment<3>(i * 3).cast<float>(); q = XMLoadFloat4A(qs.data()); q = XMQuaternionRotationRollPitchYawFromVector(q); // revert the log map XMStoreA(rots[i], q); } }
void AbsoluteEulerAngleDecoder::Encode(array_view<const DirectX::Quaternion> rots, VectorType & x) { int n = rots.size(); Eigen::Vector4f qs; XMVECTOR q; qs.setZero(); x.resize(n * 3); for (int i = 0; i < n; i++) { q = XMLoad(rots[i]); q = XMQuaternionEulerAngleYawPitchRoll(q); // Decompsoe in to euler angle XMStoreFloat4(qs.data(), q); x.segment<3>(i * 3) = qs.head<3>(); } }
void DeepData::set_all_samples (array_view<const unsigned int> samples) { if (samples.size() != size_t(m_npixels)) return; ASSERT (m_impl); if (m_impl->m_allocated) { // Data already allocated: set pixels individually for (int p = 0; p < m_npixels; ++p) set_samples (p, int(samples[p])); } else { // Data not yet allocated: copy in one shot m_impl->m_nsamples.assign (&samples[0], &samples[m_npixels]); m_impl->m_capacity.assign (&samples[0], &samples[m_npixels]); } }
bool operator == (const array_view & other) const noexcept { // Pointers to same memory (or both null). if (data() == other.data()) { return true; } // Different sizes, whole sequence can't be identical. if (size() != other.size()) { return false; } // Compare each element: return std::equal(begin(), end(), other.begin()); }
void RelativeEulerAngleDecoder::Decode(array_view<DirectX::Quaternion> rots, const VectorType & x) { int n = rots.size(); Eigen::Vector4f qs; XMVECTOR q, qb; qs.setZero(); for (int i = 0; i < n; i++) { qs.segment<3>(0) = x.segment<3>(i * 3).cast<float>(); q = XMLoadFloat4A(qs.data()); q = XMQuaternionRotationRollPitchYawFromVector(q); // revert the log map qb = XMLoadA(bases[i]); q = XMQuaternionMultiply(qb, q); XMStoreA(rots[i], q); } }
StaticArmature::StaticArmature(array_view<JointBasicData> data) { size_t jointCount = data.size(); m_joints.resize(jointCount); for (size_t i = 0; i < jointCount; i++) { m_joints[i].SetID(i); int parentID = data[i].ParentID; if (parentID != i &&parentID >= 0) { m_joints[parentID].append_children_back(&m_joints[i]); } else { m_rootIdx = i; } } CaculateTopologyOrder(); }
DecodedImage DecodeFontArt(const array_view<uint8_t> data) { // 256x256 image with 8bit alpha Expects(data.size() == 256 * 256); DecodedImage result; result.info.width = 256; result.info.height = 256; result.info.format = ImageFileFormat::FNTART; result.info.hasAlpha = true; result.data = std::make_unique<uint8_t[]>(256 * 256 * 4); auto *dest = result.data.get(); for (auto alpha : data) { *dest++ = 0xFF; *dest++ = 0xFF; *dest++ = 0xFF; *dest++ = alpha; } return result; }
array_view(array_view<ConvertibleType> other) noexcept : m_pointer{ other.data() } , m_size_in_items{ other.size() } { }
explicit mdarray(const array_view<ATYPE> &view): _imap(map_utils<map_type>::create(view.template shape<shape_t>())), _data(container_utils<storage_type>::create(view.size())) { std::copy(view.begin(),view.end(),_data.begin()); }
void DeepData::init (int npix, int nchan, array_view<const TypeDesc> channeltypes, array_view<const std::string> channelnames) { clear (); m_npixels = npix; m_nchannels = nchan; ASSERT (channeltypes.size() >= 1); if (! m_impl) m_impl = new Impl; if (int(channeltypes.size()) >= nchan) { m_impl->m_channeltypes.assign (channeltypes.data(), channeltypes.data()+nchan); } else { m_impl->m_channeltypes.clear (); m_impl->m_channeltypes.resize (m_nchannels, channeltypes[0]); } m_impl->m_channelsizes.resize (m_nchannels); m_impl->m_channeloffsets.resize (m_nchannels); m_impl->m_channelnames.resize (m_nchannels); m_impl->m_myalphachannel.resize (m_nchannels, -1); m_impl->m_samplesize = 0; m_impl->m_nsamples.resize (m_npixels, 0); m_impl->m_capacity.resize (m_npixels, 0); m_impl->m_cumcapacity.resize (m_npixels, 0); // Channel name hunt // First, find Z, Zback, A for (int c = 0; c < m_nchannels; ++c) { size_t size = m_impl->m_channeltypes[c].size(); m_impl->m_channelsizes[c] = size; m_impl->m_channeloffsets[c] = m_impl->m_samplesize; m_impl->m_samplesize += size; m_impl->m_channelnames[c] = channelnames[c]; if (m_impl->m_z_channel < 0 && is_or_endswithdot (channelnames[c], "Z")) m_impl->m_z_channel = c; else if (m_impl->m_zback_channel < 0 && is_or_endswithdot (channelnames[c], "Zback")) m_impl->m_zback_channel = c; else if (m_impl->m_alpha_channel < 0 && is_or_endswithdot (channelnames[c], "A")) m_impl->m_alpha_channel = c; else if (m_impl->m_alpha_channel < 0 && is_or_endswithdot (channelnames[c], "Alpha")) m_impl->m_alpha_channel = c; else if (m_impl->m_AR_channel < 0 && is_or_endswithdot (channelnames[c], "AR")) m_impl->m_AR_channel = c; else if (m_impl->m_AG_channel < 0 && is_or_endswithdot (channelnames[c], "AG")) m_impl->m_AG_channel = c; else if (m_impl->m_AB_channel < 0 && is_or_endswithdot (channelnames[c], "AB")) m_impl->m_AB_channel = c; } // Now try to find which alpha corresponds to each channel for (int c = 0; c < m_nchannels; ++c) { // Skip non-color channels if (c == m_impl->m_z_channel || c == m_impl->m_zback_channel || m_impl->m_channeltypes[c] == TypeDesc::UINT32) continue; string_view name (channelnames[c]); // Alpha channels are their own alpha if (is_or_endswithdot (name, "A") || is_or_endswithdot (name, "AR") || is_or_endswithdot (name, "AG") || is_or_endswithdot (name, "AB") || is_or_endswithdot (name, "Alpha")) { m_impl->m_myalphachannel[c] = c; continue; } // For anything else, try to find its channel string_view prefix = name, suffix = name; size_t dot = name.find_last_of ('.'); if (dot == string_view::npos) { // No dot prefix.clear (); } else { // dot prefix = prefix.substr (0, dot+1); suffix = suffix.substr (dot+1); } std::string targetalpha = std::string(prefix) + "A" + std::string(suffix); for (int i = 0; i < m_nchannels; ++i) { if (Strutil::iequals (m_impl->m_channelnames[i], targetalpha)) { m_impl->m_myalphachannel[c] = i; break; } } if (m_impl->m_myalphachannel[c] < 0) m_impl->m_myalphachannel[c] = m_impl->m_alpha_channel; } }