Exemplo n.º 1
0
std::unique_ptr<float[]> loadStbiHdr(const Path &path, TexelConversion request, int &w, int &h)
{
    InputStreamHandle in = FileUtils::openInputStream(path);
    if (!in)
        return nullptr;

    int channels;
    std::unique_ptr<float[], void(*)(void *)> img(stbi_loadf_from_callbacks(&istreamCallback, in.get(),
            &w, &h, &channels, 0), stbi_image_free);

    // We only expect Radiance HDR for now, which only has RGB support.
    if (!img || channels != 3)
        return nullptr;

    int targetChannels = (request == TexelConversion::REQUEST_RGB) ? 3 : 1;

    std::unique_ptr<float[]> texels(new float[w*h*targetChannels]);
    if (targetChannels == 3) {
        std::memcpy(texels.get(), img.get(), w*h*targetChannels*sizeof(float));
    } else {
        for (int i = 0; i < w*h; ++i)
            texels[i] = convertToScalar(request, img[i*3], img[i*3 + 1], img[i*3 + 2], 1.0f, false);
    }

    return std::move(texels);
}
Exemplo n.º 2
0
sk_sp<GrSurface> GrSurfaceProxy::createSurfaceImpl(GrResourceProvider* resourceProvider,
                                                   int sampleCnt, bool needsStencil,
                                                   GrSurfaceDescFlags descFlags,
                                                   GrMipMapped mipMapped) const {
    SkASSERT(GrSurfaceProxy::LazyState::kNot == this->lazyInstantiationState());
    SkASSERT(!fTarget);
    GrSurfaceDesc desc;
    desc.fFlags = descFlags;
    if (fNeedsClear) {
        desc.fFlags |= kPerformInitialClear_GrSurfaceFlag;
    }
    desc.fWidth = fWidth;
    desc.fHeight = fHeight;
    desc.fConfig = fConfig;
    desc.fSampleCnt = sampleCnt;

    // The explicit resource allocator requires that any resources it pulls out of the
    // cache have no pending IO.
    GrResourceProvider::Flags resourceProviderFlags = GrResourceProvider::Flags::kNoPendingIO;

    sk_sp<GrSurface> surface;
    if (GrMipMapped::kYes == mipMapped) {
        SkASSERT(SkBackingFit::kExact == fFit);

        // SkMipMap doesn't include the base level in the level count so we have to add 1
        int mipCount = SkMipMap::ComputeLevelCount(desc.fWidth, desc.fHeight) + 1;
        // We should have caught the case where mipCount == 1 when making the proxy and instead
        // created a non-mipmapped proxy.
        SkASSERT(mipCount > 1);
        std::unique_ptr<GrMipLevel[]> texels(new GrMipLevel[mipCount]);

        // We don't want to upload any texel data
        for (int i = 0; i < mipCount; i++) {
            texels[i].fPixels = nullptr;
            texels[i].fRowBytes = 0;
        }

        surface = resourceProvider->createTexture(desc, fBudgeted, texels.get(), mipCount);
        if (surface) {
            SkASSERT(surface->asTexture());
            SkASSERT(GrMipMapped::kYes == surface->asTexture()->texturePriv().mipMapped());
        }
    } else {
        if (SkBackingFit::kApprox == fFit) {
            surface = resourceProvider->createApproxTexture(desc, resourceProviderFlags);
        } else {
            surface = resourceProvider->createTexture(desc, fBudgeted, resourceProviderFlags);
        }
    }
    if (!surface) {
        return nullptr;
    }

    if (!GrSurfaceProxyPriv::AttachStencilIfNeeded(resourceProvider, surface.get(), needsStencil)) {
        return nullptr;
    }

    return surface;
}
Exemplo n.º 3
0
sk_sp<SkImage> SkImage::MakeFromDeferredTextureImageData(GrContext* context, const void* data,
                                                         SkBudgeted budgeted) {
    if (!data) {
        return nullptr;
    }
    const DeferredTextureImage* dti = reinterpret_cast<const DeferredTextureImage*>(data);

    if (!context || context->uniqueID() != dti->fContextUniqueID) {
        return nullptr;
    }
    int mipLevelCount = dti->fMipMapLevelCount;
    SkASSERT(mipLevelCount >= 1);
    sk_sp<SkColorSpace> colorSpace;
    if (dti->fColorSpaceSize) {
        colorSpace = SkColorSpace::Deserialize(dti->fColorSpace, dti->fColorSpaceSize);
    }
    SkImageInfo info = SkImageInfo::Make(dti->fWidth, dti->fHeight,
                                         dti->fColorType, dti->fAlphaType, colorSpace);
    if (mipLevelCount == 1) {
        SkPixmap pixmap;
        pixmap.reset(info, dti->fMipMapLevelData[0].fPixelData, dti->fMipMapLevelData[0].fRowBytes);

        // Use the NoCheck version because we have already validated the SkImage.  The |data|
        // used to be an SkImage before calling getDeferredTextureImageData().  In legacy mode,
        // getDeferredTextureImageData() will allow parametric transfer functions for images
        // generated from codecs - which is slightly more lenient than typical SkImage
        // constructors.
        sk_sp<GrTextureProxy> proxy(GrUploadPixmapToTextureProxyNoCheck(
                context->resourceProvider(), pixmap, budgeted));
        if (!proxy) {
            return nullptr;
        }
        return sk_make_sp<SkImage_Gpu>(context, kNeedNewImageUniqueID, pixmap.alphaType(),
                                       std::move(proxy), std::move(colorSpace), budgeted);
    } else {
        std::unique_ptr<GrMipLevel[]> texels(new GrMipLevel[mipLevelCount]);
        for (int i = 0; i < mipLevelCount; i++) {
            texels[i].fPixels = dti->fMipMapLevelData[i].fPixelData;
            texels[i].fRowBytes = dti->fMipMapLevelData[i].fRowBytes;
        }

        return SkImage::MakeTextureFromMipMap(context, info, texels.get(),
                                              mipLevelCount, SkBudgeted::kYes,
                                              dti->fColorMode);
    }
}
Exemplo n.º 4
0
// InfiniteAreaLight Method Definitions
InfiniteAreaLight::InfiniteAreaLight(const Transform &LightToWorld,
                                     const Spectrum &L, int nSamples,
                                     const std::string &texmap)
    : Light((int)LightFlags::Infinite, LightToWorld, MediumInterface(),
            nSamples) {
    // Read texel data from _texmap_ and initialize _Lmap_
    Point2i resolution;
    std::unique_ptr<RGBSpectrum[]> texels(nullptr);
    if (texmap != "") {
        texels = ReadImage(texmap, &resolution);
        if (texels)
            for (int i = 0; i < resolution.x * resolution.y; ++i)
                texels[i] *= L.ToRGBSpectrum();
    }
    if (!texels) {
        resolution.x = resolution.y = 1;
        texels = std::unique_ptr<RGBSpectrum[]>(new RGBSpectrum[1]);
        texels[0] = L.ToRGBSpectrum();
    }
    Lmap.reset(new MIPMap<RGBSpectrum>(resolution, texels.get()));

    // Initialize sampling PDFs for infinite area light

    // Compute scalar-valued image _img_ from environment map
    int width = 2 * Lmap->Width(), height = 2 * Lmap->Height();
    std::unique_ptr<Float[]> img(new Float[width * height]);
    float fwidth = 0.5f / std::min(width, height);
    ParallelFor(
        [&](int64_t v) {
            Float vp = (v + .5f) / (Float)height;
            Float sinTheta = std::sin(Pi * (v + .5f) / height);
            for (int u = 0; u < width; ++u) {
                Float up = (u + .5f) / (Float)width;
                img[u + v * width] = Lmap->Lookup(Point2f(up, vp), fwidth).y();
                img[u + v * width] *= sinTheta;
            }
        },
        height, 32);

    // Compute sampling distributions for rows and columns of image
    distribution.reset(new Distribution2D(img.get(), width, height));
}
Exemplo n.º 5
0
static std::unique_ptr<float[]> loadPfm(const Path &path, TexelConversion request, int &w, int &h)
{
    InputStreamHandle in = FileUtils::openInputStream(path);
    if (!in)
        return nullptr;

    std::string ident;
    *in >> ident;
    int channels;
    if (ident == "Pf")
        channels = 1;
    else if (ident == "PF")
        channels = 3;
    else
        return nullptr;
    int targetChannels = (request == TexelConversion::REQUEST_RGB) ? 3 : 1;

    *in >> w >> h;
    double s;
    *in >> s;
    std::string tmp;
    std::getline(*in, tmp);

    std::unique_ptr<float[]> img(new float[w*h*channels]);
    for (int y = 0; y < h; ++y)
        in->read(reinterpret_cast<char *>(img.get() + (h - y - 1)*w*channels), w*channels*sizeof(float));

    if (channels == targetChannels)
        return std::move(img);

    std::unique_ptr<float[]> texels(new float[w*h*targetChannels]);

    if (targetChannels == 3)
        for (int i = 0; i < w*h; ++i)
            texels[i*3] = texels[i*3 + 1] = texels[i*3 + 2] = img[i];
    else
        for (int i = 0; i < w*h; ++i)
            texels[i] = convertToScalar(request, img[i*3], img[i*3 + 1], img[i*3 + 2], 1.0f, false);

    return std::move(texels);
}
Exemplo n.º 6
0
boo::GraphicsDataToken InitializeIcons(specter::ViewResources& viewRes)
{
    athena::io::MemoryReader r(URDE_ICONS, URDE_ICONS_SZ);
    size_t fmt = r.readUint32Big();
    if (fmt != 16)
        Log.report(logvisor::Fatal, "incorrect icon texture format");
    size_t width = r.readUint16Big();
    size_t height = r.readUint16Big();
    size_t mips = r.readUint32Big();
    size_t decompSz = r.readUint32Big();

    std::unique_ptr<uint8_t[]> texels(new uint8_t[decompSz]);
    uLongf destSz = decompSz;
    size_t pos = r.position();
    if (uncompress(texels.get(), &destSz, URDE_ICONS + pos, URDE_ICONS_SZ - pos) != Z_OK)
        Log.report(logvisor::Fatal, "unable to decompress icons");

    g_IconAtlas.initializeAtlas(viewRes.m_factory->newStaticTexture(width, height, mips, boo::TextureFormat::RGBA8,
                                                                    texels.get(), destSz));
    return viewRes.m_factory->commit();
}
Exemplo n.º 7
0
sk_sp<SkImage> SkImage::MakeFromDeferredTextureImageData(GrContext* context, const void* data,
                                                         SkBudgeted budgeted) {
    if (!data) {
        return nullptr;
    }
    const DeferredTextureImage* dti = reinterpret_cast<const DeferredTextureImage*>(data);

    if (!context || context->uniqueID() != dti->fContextUniqueID) {
        return nullptr;
    }
    SkAutoTUnref<SkColorTable> colorTable;
    if (dti->fColorTableCnt) {
        SkASSERT(dti->fColorTableData);
        colorTable.reset(new SkColorTable(dti->fColorTableData, dti->fColorTableCnt));
    }
    int mipLevelCount = dti->fMipMapLevelCount;
    SkASSERT(mipLevelCount >= 1);
    sk_sp<SkColorSpace> colorSpace;
    if (dti->fColorSpaceSize) {
        colorSpace = SkColorSpace::Deserialize(dti->fColorSpace, dti->fColorSpaceSize);
    }
    SkImageInfo info = SkImageInfo::Make(dti->fWidth, dti->fHeight,
                                         dti->fColorType, dti->fAlphaType, colorSpace);
    if (mipLevelCount == 1) {
        SkPixmap pixmap;
        pixmap.reset(info, dti->fMipMapLevelData[0].fPixelData,
                     dti->fMipMapLevelData[0].fRowBytes, colorTable.get());
        return SkImage::MakeTextureFromPixmap(context, pixmap, budgeted);
    } else {
        SkAutoTDeleteArray<GrMipLevel> texels(new GrMipLevel[mipLevelCount]);
        for (int i = 0; i < mipLevelCount; i++) {
            texels[i].fPixels = dti->fMipMapLevelData[i].fPixelData;
            texels[i].fRowBytes = dti->fMipMapLevelData[i].fRowBytes;
        }

        return SkImage::MakeTextureFromMipMap(context, info, texels.get(),
                                              mipLevelCount, SkBudgeted::kYes,
                                              dti->fGammaTreatment);
    }
}
Exemplo n.º 8
0
// InfiniteAreaLight Method Definitions
InfiniteAreaLight::InfiniteAreaLight(const Transform &LightToWorld,
                                     const Spectrum &L, int nSamples,
                                     const std::string &texmap)
    : Light(LightFlags::Infinite, LightToWorld, nullptr, nSamples) {
    // Read texel data from _texmap_ and initialize _Lmap_
    Point2i resolution;
    std::unique_ptr<RGBSpectrum[]> texels(nullptr);
    if (texmap != "") {
        texels = ReadImage(texmap, &resolution);
        if (texels)
            for (int i = 0; i < resolution.x * resolution.y; ++i)
                texels[i] *= L.ToRGBSpectrum();
    }
    if (!texels) {
        resolution.x = resolution.y = 1;
        texels = std::unique_ptr<RGBSpectrum[]>(new RGBSpectrum[1]);
        texels[0] = L.ToRGBSpectrum();
    }
    Lmap.reset(new MIPMap<RGBSpectrum>(resolution, texels.get()));

    // Initialize sampling PDFs for infinite area light

    // Compute scalar-valued image _img_ from environment map
    int width = resolution.x, height = resolution.y;
    Float filter = (Float)1. / std::max(width, height);
    std::unique_ptr<Float[]> img(new Float[width * height]);
    for (int v = 0; v < height; ++v) {
        Float vp = (Float)v / (Float)height;
        Float sinTheta = std::sin(Pi * Float(v + .5f) / Float(height));
        for (int u = 0; u < width; ++u) {
            Float up = (Float)u / (Float)width;
            img[u + v * width] = Lmap->Lookup(Point2f(up, vp), filter).y();
            img[u + v * width] *= sinTheta;
        }
    }

    // Compute sampling distributions for rows and columns of image
    distribution.reset(new Distribution2D(img.get(), width, height));
}
Exemplo n.º 9
0
static std::unique_ptr<float[]> loadExr(const Path &path, TexelConversion request, int &w, int &h)
{
    InputStreamHandle inputStream = FileUtils::openInputStream(path);
    if (!inputStream)
        return nullptr;

    try {

    ExrIStream in(std::move(inputStream));
    Imf::InputFile file(in);
    Imath::Box2i dataWindow = file.header().dataWindow();
    w = dataWindow.max.x - dataWindow.min.x + 1;
    h = dataWindow.max.y - dataWindow.min.y + 1;
    int dx = dataWindow.min.x;
    int dy = dataWindow.min.y;

    const Imf::ChannelList &channels = file.header().channels();
    const Imf::Channel *rChannel = channels.findChannel("R");
    const Imf::Channel *gChannel = channels.findChannel("G");
    const Imf::Channel *bChannel = channels.findChannel("B");
    const Imf::Channel *aChannel = channels.findChannel("A");
    const Imf::Channel *yChannel = channels.findChannel("Y");

    Imf::FrameBuffer frameBuffer;

    bool isScalar = request != TexelConversion::REQUEST_RGB;
    bool acceptsAlpha =
            request == TexelConversion::REQUEST_ALPHA ||
            request == TexelConversion::REQUEST_AUTO;
    int targetChannels = isScalar ? 1 : 3;
    int sourceChannels = (rChannel ? 1 : 0) + (gChannel ? 1 : 0) + (bChannel ? 1 : 0);

    std::unique_ptr<float[]> texels(new float[w*h*targetChannels]);
    std::unique_ptr<float[]> img;
    size_t texelSize = sizeof(float)*targetChannels;
    char *base = reinterpret_cast<char *>(texels.get() - (dx + dy*w)*targetChannels);

    if (isScalar && (yChannel != nullptr || (acceptsAlpha && aChannel != nullptr))) {
        // The user requested a scalar texture and the file either contains an alpha channel or a luminance channel
        // The alpha channel is only allowed if it was explicitly requested or an auto conversion was requested
        // RGB -> Scalar falls through and is handled later
        const char *channelName = (acceptsAlpha && aChannel != nullptr) ? "A" : "Y";
        frameBuffer.insert(channelName, Imf::Slice(Imf::FLOAT, base, texelSize, texelSize*w));
    } else if (!isScalar && (rChannel || gChannel || bChannel)) {
        // The user wants RGB and we have (some) RGB channels
        if (rChannel) frameBuffer.insert("R", Imf::Slice(Imf::FLOAT, base + 0*sizeof(float), texelSize, texelSize*w));
        if (gChannel) frameBuffer.insert("G", Imf::Slice(Imf::FLOAT, base + 1*sizeof(float), texelSize, texelSize*w));
        if (bChannel) frameBuffer.insert("B", Imf::Slice(Imf::FLOAT, base + 2*sizeof(float), texelSize, texelSize*w));
        // If some channels are missing, replace them with black
        if (!rChannel || !gChannel || !bChannel)
            std::memset(texels.get(), 0, texelSize*w*h);
    } else if (!isScalar && yChannel) {
        // The user wants RGB and we have just luminance -> duplicate luminance across all three channels
        // This is not the best solution, but we don't want to deal with chroma subsampled images
        frameBuffer.insert("Y", Imf::Slice(Imf::FLOAT, base, texelSize, texelSize*w));
    } else if (isScalar) {
        // The user wants a scalar texture and we have (some) RGB channels
        // We can't read directly into the destination, but have to read to a temporary
        // and do a conversion to scalar later
        img.reset(new float[sourceChannels*w*h]);
        char *imgBase = reinterpret_cast<char *>(img.get() - (dx + dy*w)*sourceChannels);

        const Imf::Channel *channels[] = {rChannel, gChannel, bChannel};
        const char *channelNames[] = {"R", "G", "B"};
        int texel = 0;
        for (int i = 0; i < 3; ++i) {
            if (channels[i]) {
                frameBuffer.insert(channelNames[i], Imf::Slice(Imf::FLOAT, imgBase + texel*sizeof(float),
                        sourceChannels*sizeof(float), sourceChannels*sizeof(float)*w));
                texel++;
            }
        }
    } else {
        return false;
    }

    file.setFrameBuffer(frameBuffer);
    file.readPixels(dataWindow.min.y, dataWindow.max.y);

    if (img) {
        // We only get here if we need to make a scalar texture from an RGB input
        int texel = 0;
        int rLocation = -1, gLocation = -1, bLocation = -1;
        if (rChannel) rLocation = texel++;
        if (gChannel) gLocation = texel++;
        if (bChannel) bLocation = texel++;

        for (int i = 0; i < w*h; ++i) {
            float r = rChannel ? img[i*sourceChannels + rLocation] : 0.0f;
            float g = gChannel ? img[i*sourceChannels + gLocation] : 0.0f;
            float b = bChannel ? img[i*sourceChannels + bLocation] : 0.0f;
            texels[i] = convertToScalar(request, r, g, b, 0.0f, false);
        }
    } else if (!isScalar && yChannel) {
        // Here we need to duplicate the Y channel stored in R across G and B
        for (int i = 0; i < w*h; ++i)
            texels[i*3 + 1] = texels[i*3 + 2] = texels[i*3];
    }

    return std::move(texels);

    } catch(const std::exception &e) {
        std::cout << "OpenEXR loader failed: " << e.what() << std::endl;
        return nullptr;
    }
}