Пример #1
0
bool Bitmap::loadEXR(const char* filename)
{
	try {
		Imf::RgbaInputFile exr(filename);
		Imf::Array2D<Imf::Rgba> pixels;
		Imath::Box2i dw = exr.dataWindow();
		width  = dw.max.x - dw.min.x + 1;
		height = dw.max.y - dw.min.y + 1;
		pixels.resizeErase(height, width);
		exr.setFrameBuffer(&pixels[0][0] - dw.min.x - dw.min.y * width, 1, width);
		exr.readPixels(dw.min.y, dw.max.y);
		data = new Color[width * height];
		for (int y = 0; y < height; y++)
			for (int x = 0; x < width; x++) {
				Color& pixel = data[y * width + x];
				pixel.r = pixels[y + dw.min.y][x + dw.min.x].r;
				pixel.g = pixels[y + dw.min.y][x + dw.min.x].g;
				pixel.b = pixels[y + dw.min.y][x + dw.min.x].b;
			}
		return true;
	}
	catch (Iex::BaseExc ex) {
		width = height = 0;
		data = NULL;
		return false;
	}
}
Пример #2
0
////////////////////////////////////////////////////////////////////////////
// Take a file name/location and load an OpenEXR
// Load the image into the "texture" texture object and pass back the texture sizes
// 
bool LoadOpenEXRImage(char *fileName, GLint textureName, GLuint &texWidth, GLuint &texHeight)
{
    // The OpenEXR uses exception handling to report errors or failures
    // Do all work in a try block to catch any thrown exceptions.
    try
    {
        Imf::Array2D<Imf::Rgba> pixels;
        Imf::RgbaInputFile file (fileName);
        Imath::Box2i dw = file.dataWindow();

        texWidth  = dw.max.x - dw.min.x + 1;
        texHeight = dw.max.y - dw.min.y + 1;
        
        pixels.resizeErase (texHeight, texWidth); 

        file.setFrameBuffer (&pixels[0][0] - dw.min.x - dw.min.y * texWidth, 1, texWidth);
        file.readPixels (dw.min.y, dw.max.y); 

        GLfloat* texels = (GLfloat*)malloc(texWidth * texHeight * 3 * sizeof(GLfloat));
        GLfloat* pTex = texels;

        // Copy OpenEXR into local buffer for loading into a texture
        for (unsigned int v = 0; v < texHeight; v++)
        {
            for (unsigned int u = 0; u < texWidth; u++)
            {
                Imf::Rgba texel = pixels[texHeight - v - 1][u];  
                pTex[0] = texel.r;
                pTex[1] = texel.g;
                pTex[2] = texel.b;

                pTex += 3;
            }
        }

        // Bind texture, load image, set tex state
        glBindTexture(GL_TEXTURE_2D, textureName);
        glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB16F, texWidth, texHeight, 0, GL_RGB, GL_FLOAT, texels);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
        
        free(texels);
    }
    catch(Iex::BaseExc & e)  
    {
        std::cerr << e.what() << std::endl;
        //
        // Handle exception.
        //
    }

    return true;
}
Пример #3
0
 template<class T> Array<Vector<T,3>,2> ExrFile<T>::
 read(const std::string& filename)
 {
   Imf::RgbaInputFile file(filename.c_str());
   Imath::Box2i dw = file.dataWindow();
   int width = dw.max.x - dw.min.x + 1;
   int height = dw.max.y - dw.min.y + 1;
   Imf::Array2D<Imf::Rgba> pixels;
   pixels.resizeErase(height, width);
   file.setFrameBuffer(&pixels[0][0] - dw.min.x - dw.min.y * width, 1, width);
   file.readPixels(dw.min.y, dw.max.y);
   
   Array<Vector<T,3>,2> image(width, height);
   for (int i = 0; i < image.m; ++i) {
     for (int j = 0; j < image.n; ++j) {
       image(i,j) = from_rgba<T>(pixels[j][i]);
     }
   }
   return image;
 }
Пример #4
0
void make_preview(Imf::RgbaInputFile &in,
                   float exposure,
                   int previewWidth,
                   int previewHeight,
                   Imf::Array2D <Imf::PreviewRgba> &previewPixels)
    {
    //
    // Read image
    //
    Box2i dw = in.dataWindow();
    int w = dw.max.x - dw.min.x + 1;
    int h = dw.max.y - dw.min.y + 1;

    Array2D <Rgba> pixels (h, w);
    in.setFrameBuffer (&pixels[0][0] - dw.min.y * w - dw.min.x, 1, w);
    in.readPixels (dw.min.y, dw.max.y);

    //
    // Make a preview image
    //
    previewPixels.resizeErase (previewHeight, previewWidth);

    float fx = (previewWidth  > 0)? (float (w - 1) / (previewWidth  - 1)): 1;
    float fy = (previewHeight > 0)? (float (h - 1) / (previewHeight - 1)): 1;
    float m  = Math<float>::pow (2.f, clamp (exposure + 2.47393f, -20.f, 20.f));

    for (int y = 0; y < previewHeight; ++y)
    {
        for (int x = 0; x < previewWidth; ++x)
        {
            PreviewRgba &preview = previewPixels[y][x];
            const Rgba &pixel = pixels[int (y * fy + .5f)][int (x * fx + .5f)];

            preview.r = gamma (pixel.r, m);
            preview.g = gamma (pixel.g, m);
            preview.b = gamma (pixel.b, m);
            preview.a = int (clamp (pixel.a * 255.f, 0.f, 255.f) + .5f);
        }
    }
}
Пример #5
0
/*!
    Tries to fill the image object with the data read from
    the given input stream. Returns true on success.
*/
bool EXRImageFileType::read(      Image        *image, 
                                  std::istream &is, 
                            const std::string  &mimetype)
{
#ifdef OSG_WITH_IMF
    if (!is.good())
        return false;

    const char *dummy = "";
    StdIStream file(is, dummy);

    Imf::Int64 pos = file.tellg();

    bool check = isOpenExrFile(is);

    file.seekg(pos);

    if (!check)
    {
        FFATAL(( "Wrong format, no %s image given!\n",
                  mimetype.c_str() ));
        return false;
    }

    // just read the header and get the channel count
    int channel_count = 0;
    pos = file.tellg();
    try
    {
        Imf::RgbaInputFile stream(file);
        const Imf::Header &header = stream.header();
        const Imf::ChannelList &channels = header.channels();

        for(Imf::ChannelList::ConstIterator it  = channels.begin();
                                            it != channels.end();
                                          ++it)
        {
            ++channel_count;
        }
    }
    catch(std::exception &e)
    {
        FFATAL(( "Error while trying to read OpenEXR Image from stream: %s\n",
                  e.what() ));
        return false;
    }
    file.seekg(pos);

    if(channel_count <= 4)
    {
        // TODO: check for mipmap levels,
        // look if line order is s.th. else than INCREASING_Y
        try
        {
            Int32 width, height, numImg = 1;
            Imf::RgbaInputFile stream(file);
    
            Imath::Box2i dw = stream.dataWindow();
            Imf::Array2D<Imf::Rgba> pixels;
    
            const Imf::Header &header = stream.header();
//            const Imf::LineOrder &order = header.lineOrder();
    
            const Imf::EnvmapAttribute *envmap =
                header.findTypedAttribute<Imf::EnvmapAttribute>("envmap");
    
            width  = dw.max.x - dw.min.x + 1;
            height = dw.max.y - dw.min.y + 1;
    
            pixels.resizeErase(height, width);
    
            if(envmap && envmap->value() == Imf::ENVMAP_CUBE)
            {
                numImg = 6;
                height /= numImg;
    
                if (width != height)
                {
                    FFATAL(( "Cubemaps must have squared size, "
                             "but w=%d and h=%d!\n", width, height ));
                    return false;
                }
            }
    
            stream.setFrameBuffer(&pixels[0][0] - dw.min.x - dw.min.y * width,
                                  1, 
                                  width);
            stream.readPixels(dw.min.y, dw.max.y);
    
            image->set( Image::OSG_RGBA_PF, width, height, 1, 1, 1, 0, 0,
                        Image::OSG_FLOAT16_IMAGEDATA, true, numImg );
            image->clearHalf();
    
            // now add custom attributes
            for(Imf::Header::ConstIterator it  = header.begin();
                                           it != header.end();
                                         ++it)
            {
                Imf::Attribute *copy = it.attribute().copy();
                Imf::StringAttribute *sa = 
                    dynamic_cast<Imf::StringAttribute *>(copy);
    
                if(sa != NULL)
                    image->setAttachmentField(it.name(), sa->value());
    
                delete copy;
            }
    
            Real16 *data = reinterpret_cast<Real16*>(image->editData());
    
            for (Int32 side=numImg-1; side >=0; side--)
            {
                Int32 i, j, size = side * width * height * 4;
    
                for (Int32 y=side*height; y<(side+1)*height; y++)
                {
                    for (Int32 x=0; x<width; x++)
                    {
                        if (numImg == 1 || side == 2 || side == 3)
                        {
                            i = (2 * side + 1) * height - (y + 1); // new y
                            j = x;
                        }
                        else
                        {
                            i = y;
                            j = width - x - 1; // new x
                        }
    
                        *(data + size++) = Real16(pixels[i][j].r);
                        *(data + size++) = Real16(pixels[i][j].g);
                        *(data + size++) = Real16(pixels[i][j].b);
                        *(data + size++) = Real16(pixels[i][j].a);
                    }
                }
            }
    
            return true;
        }
        catch(std::exception &e)
        {
            FFATAL(( "Error while trying to read OpenEXR Image from stream: "
                     "%s\n", e.what() ));

            return false;
        }
    }
    else
    {
        try
        {
            if(channel_count % 4 != 0)
            {
                FFATAL(( "Error while trying to read OpenEXR Image from "
                         "stream, channel count of %d is not supported!\n", 
                         channel_count));

                return false;
            }

            int num_img = channel_count / 4;

            Imf::InputFile stream(file);
            const Imf::Header &header = stream.header();
            Imath::Box2i dw = header.dataWindow();

            int width  = dw.max.x - dw.min.x + 1;
            int height = dw.max.y - dw.min.y + 1;

            image->set(Image::OSG_RGBA_PF, width, height, 1, 1, 1, 0, 0,
                       Image::OSG_FLOAT16_IMAGEDATA, true, num_img);
            image->clearHalf();

            // now add custom attributes
            for(Imf::Header::ConstIterator it  = header.begin();
                                           it != header.end();
                                         ++it                  )
            {
                Imf::Attribute *copy = it.attribute().copy();
                Imf::StringAttribute *sa = 
                    dynamic_cast<Imf::StringAttribute *>(copy);
    
                if(sa != NULL)
                    image->setAttachmentField(it.name(), sa->value());
    
                delete copy;
            }

            const Imf::ChannelList &channels = header.channels();

            // do some channel name checks
            bool channel_error = false;
            for(Imf::ChannelList::ConstIterator it=channels.begin();it!=channels.end();++it)
            {
                for(int side=0;side>num_img;++side)
                {
                    char cn[20];
                    sprintf(cn, "%d", side);

                    char name[20];
                    sprintf(name, "R%s", side == 0 ? "" : cn);
                    if(channels.findChannel(name) == NULL)
                        channel_error = true;
                    sprintf(name, "G%s", side == 0 ? "" : cn);
                    if(channels.findChannel(name) == NULL)
                        channel_error = true;
                    sprintf(name, "B%s", side == 0 ? "" : cn);
                    if(channels.findChannel(name) == NULL)
                        channel_error = true;
                    sprintf(name, "A%s", side == 0 ? "" : cn);
                    if(channels.findChannel(name) == NULL)
                        channel_error = true;
                }
            }

            if(channel_error)
            {
                FFATAL(( "Error while trying to read OpenEXR Image from "
                         "stream, expected channel names 'R' 'G' 'B' 'A', "
                         "'R1' 'G1', 'B1', 'A1', ...\n"));

                return false;
            }

            Imf::FrameBuffer frame_buffer;

            // we need to do a vertical flip so we read single scan lines in.
            int current_scan_line = 0;
            for(int i=height-1;i>=0;--i)
            {
                for(int side=0;side<num_img;++side)
                {
                    char *data = 
                        (reinterpret_cast<char *>(image->editData(0, 0, side))) + i * (sizeof(Real16) * 4 * width);

                    data -= current_scan_line * (sizeof(Real16) * 4 * width);

                    char cn[20];
                    sprintf(cn, "%d", side);

                    char name[20];
                    sprintf(name, "R%s", side == 0 ? "" : cn);
                    frame_buffer.insert(name, Imf::Slice(Imf::HALF, data, sizeof(Real16) * 4, sizeof(Real16) * 4 * width));
                    sprintf(name, "G%s", side == 0 ? "" : cn);
                    frame_buffer.insert(name, Imf::Slice(Imf::HALF, data + 1 * sizeof(Real16), sizeof(Real16) * 4, sizeof(Real16) * 4 * width));
                    sprintf(name, "B%s", side == 0 ? "" : cn);
                    frame_buffer.insert(name, Imf::Slice(Imf::HALF, data + 2 * sizeof(Real16), sizeof(Real16) * 4, sizeof(Real16) * 4 * width));
                    sprintf(name, "A%s", side == 0 ? "" : cn);
                    frame_buffer.insert(name, Imf::Slice(Imf::HALF, data + 3 * sizeof(Real16), sizeof(Real16) * 4, sizeof(Real16) * 4 * width));
                }
                stream.setFrameBuffer(frame_buffer);
                stream.readPixels(current_scan_line, current_scan_line);
                ++current_scan_line;
            }

            return true;
        }
        catch(std::exception &e)
        {
            FFATAL(( "Error while trying to read OpenEXR Image from stream: %s\n",
                      e.what() ));
            return false;
        }
    }

#else
    SWARNING << getMimeType()
             << " read is not compiled into the current binary "
             << std::endl;
    return false;
#endif
}
Пример #6
0
int main(int argc, char** argv) {
	//clock_t start = clock();
	//glutInit(&argc, argv);
	//glutInitDisplayMode(GLUT_DEPTH | GLUT_DOUBLE | GLUT_RGBA);
	std::cout << argc << endl;
	if (argc == 3) {
		name = argv[2];
	} else if (argc == 2) {
		name = argv[1];
		name = name.substr(0, name.find_last_of('.')) + ".exr";
	} else {
		/*clock_t start = clock();
		srand(time(NULL));
#define __R rand() / (double)RAND_MAX
#define __VR Vector3d(__R, __R, __R)
		Sphere* ss = new Sphere(Vector3d(__R, __R, __R), __R, new Material(Vector3d::Ones, Vector3d::Ones, Vector3d::Ones, 0, Vector3d::Ones, 0, Vector3d::Ones));
		bool result = false;
		hitRecord r;
		for (int i = 0; i < 1e6; i++) {
			result = ss->hit(Ray(__VR, __VR, std::vector<double>(), std::vector<Vector3d>(), Ray::VIEW), nINF, INF, r);
		}
		clock_t ends = clock();
		double runtime = (double) (ends - start) / CLOCKS_PER_SEC;
		cout << runtime << " seconds" << endl;
		return result;*/
		/*
		Interval i(0, 1);
		cout << i << endl;
		cout << "should be true: " << Interval::intersects(i, Interval(-1, 0.5)) << endl;
		cout << "============= binary Intersects ============" << endl;
		cout << "should be (0, 0.5): " << i.intersect(Interval(-1, 0.5)) << endl;
		cout << "should be (0.2, 0.8): " << i.intersect(Interval(0.2, 0.8)) << endl;
		cout << "should be (0.5, 1): " << i.intersect(Interval(0.5, 4)) << endl;
		cout << "should be (): " << i.intersect(Interval(9, 10)) << endl;
		cout << "should be (): " << i.intersect(Interval()) << endl;
		cout << "============= binary Unions ================" << endl;
		cout << "should be (0, 4) and (0, 4): " << i.unionize(Interval(1, 4)) << " " << i.unionize(Interval(0.5, 4)) << endl;
		cout << "should be {(0, 1), (5, 6)}: " << i.unionize(Interval(5, 6)) << endl;
		cout << "should be {(-5, -3), (0, 1)}: " << i.unionize(Interval(-5, -3)) << endl;
		cout << "should be (-5, 5): " << i.unionize(Interval(-5, 5)) << endl;
		cout << "should be (0, 1): " << i.unionize(Interval()) << endl;
		cout << "============= binary Differences ===========" << endl;
		Interval k(-5, 5);
		cout << "should be {(-5, -2), (2, 5)}: " << k.difference(Interval(-2, 2)) << endl;
		cout << "should be (0, 5): " << k.difference(Interval(-5, 0)) << endl;
		cout << "should be (-5, 0): " << k.difference(Interval(0, 5)) << endl;
		cout << "should be (): " << k.difference(k) << endl;
		cout << "should be (): " << k.difference(Interval(-10, 10)) << endl;
		cout << "should be (-5, 5): " << k.difference(Interval(10, 20)) << endl;
		cout << "should be (-5, 5): " << k.difference(Interval(-20, -10)) << endl;
		cout << "should be (-5, 5): " << k.difference(Interval()) << endl;
		cout << "should be (): " << Interval().difference(k) << endl;
		cout << "============= Multiple Unions ==============" << endl;
		Intervals j;
		j.push_back(Interval(-1, 1));
		j.push_back(Interval(1.5, 2));
		j.push_back(Interval(2.5, 3));
		//j = Interval::unionize(j);
		cout << "{(-1, 1), (1.5, 2), (2.5, 3)}: " << j << endl;
		Intervals x = j;
		x.push_back(Interval(2, 4));
		//x = Interval::unionize(x);
		cout << "{(-1, 1), (1.5, 4)}: " << x << endl;
		x = j;
		x.push_back(Interval(-5, 5));
		//cout << "{(-5, 5)}: " << Interval::unionize(x) << endl;
		Intervals y; y.push_back(Interval(0, 2)); y.push_back(Interval(3, 4)); y.push_back(Interval(-3, -2));
		x.pop_back(); x.insert(x.end(), y.begin(), y.end());
		//cout << x << endl << Interval::unionize(x) << endl;
		exit(0);*/
	}
	tracer.parse(argv[1]);
	width = tracer.width;
	height = tracer.height;
	pixels = new unsigned int[width * height];
	for (int i = 0; i < width * height; i++) {
		pixels[i] = 0;
	}
	o.resizeErase (height, width);
	cout << endl << width << " " << height << endl;
	clock_t start = clock();
	tracer.render(o);
	clock_t ends = clock();
	double runtime = (double) (ends - start) / CLOCKS_PER_SEC;
	cout << runtime << " seconds" << endl;
	writeRgba(name.c_str(), &o[0][0], width, height);
	return 0;
	//glutInitWindowPosition(0,0);
	//glutInitWindowSize(width,height);
	//glWindow = glutCreateWindow("RayTra");
	//glViewport(0, 0, width, height);
	//glMatrixMode(GL_PROJECTION);
	//glLoadIdentity();
	//gluOrtho2D(0, width, 0, height);
	//glMatrixMode(GL_MODELVIEW);
	//glLoadIdentity();
	//glClearColor(0.0, 0.0, 0.0, 0.0);
	//glutDisplayFunc(display);
	//glutIdleFunc(idle);
	//glutKeyboardFunc(keylistener);
	//glDisable(GL_DEPTH_TEST);
	//glutMainLoop();
	//clock_t ends = clock();
	//double runtime = (double) (ends - start) / CLOCKS_PER_SEC;
	//std::cout << "Elapsed: " << runtime << std::endl;
}
Пример #7
0
 ChannelInfo( int inStride, int inDim1, int inDim2)
 {
    stride = inStride;
    array2d.resizeErase( inDim1 * stride, inDim2);
 }