Exemple #1
0
Image *Read(IStream *file, const Image::ReadOptions& options)
{
	unsigned int width;
	unsigned int height;
	Image  *image = NULL;

	// OpenEXR files store linear color values by default, so never convert unless the user overrides
	// (e.g. to handle a non-compliant file).
	GammaCurvePtr gamma;
	if (options.gammacorrect)
	{
		if (options.gammaOverride)
			gamma = TranscodingGammaCurve::Get(options.workingGamma, options.defaultGamma);
		else
			gamma = TranscodingGammaCurve::Get(options.workingGamma, NeutralGammaCurve::Get());
	}

	// OpenEXR officially uses premultiplied alpha, so that's the preferred mode to use for the image container unless the user overrides
	// (e.g. to handle a non-compliant file).
	bool premul = true;
	if (options.premultiplyOverride)
		premul = options.premultiply;

	// TODO: code this to observe the request for alpha in the input file type.
	POV_EXR_IStream is(*file);
	try
	{
		RgbaInputFile rif(is);
		Array2D<Rgba> pixels;
		Box2i dw = rif.dataWindow();
		Image::ImageDataType imagetype = options.itype;

		width = dw.max.x - dw.min.x + 1;
		height = dw.max.y - dw.min.y + 1;
		pixels.resizeErase(height, width);
		rif.setFrameBuffer(&pixels[0][0] - dw.min.x - dw.min.y * width, 1, width);
		rif.readPixels(dw.min.y, dw.max.y);

		if(imagetype == Image::Undefined)
			imagetype = Image::RGBFT_Float;

		image = Image::Create(width, height, imagetype);
		image->SetPremultiplied(premul); // set desired storage mode regarding alpha premultiplication

		for(int row = 0; row < height; row++)
		{
			for(int col = 0; col < width; col++)
			{
				struct Rgba &rgba = pixels [row][col];
				SetEncodedRGBAValue(image, col, row, gamma, (float)rgba.r, (float)rgba.g, (float)rgba.b, (float)rgba.a, premul);
			}
		}
	}
	catch(const std::exception& e)
	{
		throw POV_EXCEPTION(kFileDataErr, e.what());
	}

	return image;
}
void
readTiled1 (const char fileName[],
            Array2D<GZ> &pixels,
            int &width, int &height)
{
    TiledInputFile in (fileName);

    Box2i dw = in.header().dataWindow();
    width  = dw.max.x - dw.min.x + 1;
    height = dw.max.y - dw.min.y + 1;
    int dx = dw.min.x;
    int dy = dw.min.y;

    pixels.resizeErase (height, width);

    FrameBuffer frameBuffer;

    frameBuffer.insert ("G",					 // name
                        Slice (HALF,				 // type
			       (char *) &pixels[-dy][-dx].g,	 // base
				sizeof (pixels[0][0]) * 1,	 // xStride
				sizeof (pixels[0][0]) * width)); // yStride

    frameBuffer.insert ("Z",					 // name
                        Slice (FLOAT,				 // type
			       (char *) &pixels[-dy][-dx].z,	 // base
				sizeof (pixels[0][0]) * 1,	 // xStride
				sizeof (pixels[0][0]) * width)); // yStride

    in.setFrameBuffer (frameBuffer);
    in.readTiles (0, in.numXTiles() - 1, 0, in.numYTiles() - 1);
}
Exemple #3
0
void
readRgba (const char fileName[],
          Array2D<Rgba> &pixels,
          int &width,
          int &height)
{
    //
    // Read an RGBA image using class RgbaInputFile:
    //
    //	- open the file
    //	- allocate memory for the pixels
    //	- describe the memory layout of the pixels
    //	- read the pixels from the file
    //
    
    RgbaInputFile file (fileName);
    Box2i dw = file.dataWindow();
    
    width  = dw.max.x - dw.min.x + 1;
    height = dw.max.y - dw.min.y + 1;
    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);
}
static void readRgba1(const std::string& filename, Array2D<Rgba>& pixels,
                      int& width, int& height) {
  RgbaInputFile file{filename.c_str()};
  Box2i dw = file.dataWindow();
  width    = dw.max.x - dw.min.x + 1;
  height = dw.max.y - dw.min.y + 1;
  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);
}
void Exr::readRgba(const string inf, Array2D<Rgba> &pix, int &w, int &h)
{
    RgbaInputFile file (inf.c_str());
    Box2i dw = file.dataWindow();
    w  = dw.max.x - dw.min.x + 1;
    h = dw.max.y - dw.min.y + 1;
    pix.resizeErase (h, w);
    file.setFrameBuffer (&pix[0][0] - dw.min.x - dw.min.y * w, 1, w);
    file.readPixels (dw.min.y, dw.max.y);
}
void
readRgba1 (const char fileName[],
    Array2D<Rgba> &pixels,
    int &width,
    int &height)
// from openexr-1.7.0/doc/ReadingAndWritingImageFiles.pdf page 6
{
  RgbaInputFile file (fileName);
  Box2i dw = file.dataWindow();
  width = dw.max.x - dw.min.x + 1;
  height = dw.max.y - dw.min.y + 1;
  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);
}
void
readTiledRgba1 (const char fileName[],
                Array2D<Rgba> &pixels,
                int &width,
                int &height)
{
    TiledRgbaInputFile in (fileName);
    Box2i dw = in.dataWindow();

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

    pixels.resizeErase (height, width);

    in.setFrameBuffer (&pixels[-dy][-dx], 1, width);
    in.readTiles (0, in.numXTiles() - 1, 0, in.numYTiles() - 1);
}
void
readGZ2 (const char fileName[],
	 Array2D<GZ> &pixels,
	 int &width, int &height)
{
    //
    // Read an image using class InputFile.  Try to read one channel,
    // G, of type HALF, and one channel, Z, of type FLOAT.  In memory,
    // the G and Z channels will be interleaved in a single buffer.
    //
    //	- open the file
    //	- allocate memory for the pixels
    //	- describe the layout of the GZ pixel buffer
    //	- read the pixels from the file
    //

    InputFile file (fileName);

    Box2i dw = file.header().dataWindow();
    width  = dw.max.x - dw.min.x + 1;
    height = dw.max.y - dw.min.y + 1;
    int dx = dw.min.x;
    int dy = dw.min.y;

    pixels.resizeErase (height, width);

    FrameBuffer frameBuffer;

    frameBuffer.insert ("G",					 // name
                        Slice (IMF::HALF,			 // type
			       (char *) &pixels[-dy][-dx].g,	 // base
				sizeof (pixels[0][0]) * 1,	 // xStride
				sizeof (pixels[0][0]) * width)); // yStride

    frameBuffer.insert ("Z",					 // name
                        Slice (IMF::FLOAT,			 // type
			       (char *) &pixels[-dy][-dx].z,	 // base
				sizeof (pixels[0][0]) * 1,	 // xStride
				sizeof (pixels[0][0]) * width)); // yStride

    file.setFrameBuffer (frameBuffer);
    file.readPixels (dw.min.y, dw.max.y);
}
Exemple #9
0
KDE_EXPORT void kimgio_exr_read( TQImageIO *io )
{
    try
    {
		int width, height;

		// This won't work if io is not TQFile !
		RgbaInputFile file (TQFile::encodeName(io->fileName()));
		Imath::Box2i dw = file.dataWindow();

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

		Array2D<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);

		TQImage image(width, height, 32, 0, TQImage::BigEndian);
		if( image.isNull())
			return;

		// somehow copy pixels into image
		for ( int y=0; y < height; y++ ) {
			for ( int x=0; x < width; x++ ) {
				// copy pixels(x,y) into image(x,y)
				image.setPixel( x, y, RgbaToQrgba( pixels[y][x] ) );
			}
		}

		io->setImage( image );
		io->setStatus( 0 );
    }
    catch (const std::exception &exc)
    {
		kdDebug(399) << exc.what() << endl;
        return;
    }
}
void AVPCL::decompress(string avpclf, string outf)
{
	Array2D<RGBA> pixels;
	int w, h;
	char block[AVPCL::BLOCKSIZE];

	extract(avpclf, w, h, AVPCL::mode_rgb);
	FILE *avpclfile = fopen(avpclf.c_str(), "rb");
	if (avpclfile == NULL) throw "Unable to open .avpcl file for read";
	pixels.resizeErase(h, w);

	// convert to tiles and decompress each tile
	for (int y=0; y<h; y+=Tile::TILE_H)
	{
		int ysize = MIN(Tile::TILE_H, h-y);
		for (int x=0; x<w; x+=Tile::TILE_W)
		{
			int xsize = MIN(Tile::TILE_W, w-x);
			Tile t(xsize, ysize);

			if (fread(block, sizeof(char), AVPCL::BLOCKSIZE, avpclfile) != AVPCL::BLOCKSIZE)
				throw "File error on read";

			stats(block);	// collect statistics
		
			AVPCL::decompress(block, t);

			t.extract(pixels, x, y);
		}
	}
	if (fclose(avpclfile)) throw "Close failed on .avpcl file";

	Targa::write(outf, pixels, w, h);

	printstats();	// print statistics
}
Exemple #11
0
unsigned char *exr_load(std::istream& fin,
                        int *width_ret,
                        int *height_ret,
                        int *numComponents_ret,
                        unsigned int *dataType_ret)
{
    unsigned char *buffer=NULL; // returned to sender & as read from the disk
    bool inputError = false;
    Array2D<Rgba> pixels;
    int width,height,numComponents;

    try
    {
        C_IStream inStream(&fin);
        RgbaInputFile rgbafile(inStream);

        Box2i dw = rgbafile.dataWindow();
        /*RgbaChannels channels =*/ rgbafile.channels();
        (*width_ret) = width = dw.max.x - dw.min.x + 1;
        (*height_ret)=height = dw.max.y - dw.min.y + 1;
        (*dataType_ret) = GL_HALF_FLOAT_ARB;

        pixels.resizeErase (height, width);

        rgbafile.setFrameBuffer((&pixels)[0][0] - dw.min.x - dw.min.y * width, 1, width);
        rgbafile.readPixels(dw.min.y, dw.max.y);
    }
    catch( char * str ) {
        inputError = true;
    }

    //If error during stream read return a empty pointer
    if (inputError)
    {
        return buffer;
    }

    //If there is no information in alpha channel do not store the alpha channel
    numComponents = 3;
    for (long i = height-1; i >= 0; i--)
    {
        for (long j = 0 ; j < width; j++)
        {
            if (pixels[i][j].a != half(1.0f) )
            {
                numComponents = 4;
                break;
            }
        }
    }
    (*numComponents_ret) = numComponents;

    if (!(    numComponents == 3 ||
              numComponents == 4))
    {
        return NULL;
    }

    //Copy and allocate data to a unsigned char array that OSG can use for texturing
    unsigned dataSize = (sizeof(half) * height * width * numComponents);
    //buffer = new unsigned char[dataSize];
    buffer = (unsigned char*)malloc(dataSize);
    half* pOut = (half*) buffer;

    for (long i = height-1; i >= 0; i--)
    {
        for (long j = 0 ; j < width; j++)
        {
            (*pOut) = pixels[i][j].r;
            pOut++;
            (*pOut) = pixels[i][j].g;
            pOut++;
            (*pOut) = pixels[i][j].b;
            pOut++;
            if (numComponents >= 4)
            {
                (*pOut) = pixels[i][j].a;
                pOut++;
            }
        }
    }

    return buffer;
}
void
readGZ1 (const char fileName[],
	 Array2D<half> &rPixels,
	 Array2D<half> &gPixels,
	 Array2D<float> &zPixels,
	 int &width, int &height)
{
    //
    // Read an image using class InputFile.  Try to read two
    // channels, R and G, of type HALF, and one channel, Z,
    // of type FLOAT.  Store the R, G, and Z pixels in three
    // separate memory buffers.
    // If a channel is missing in the file, the buffer for that
    // channel will be filled with an appropriate default value.
    //
    //	- open the file
    //	- allocate memory for the pixels
    //	- describe the layout of the R, G, and Z pixel buffers
    //	- read the pixels from the file
    //

    InputFile file (fileName);

    Box2i dw = file.header().dataWindow();
    width  = dw.max.x - dw.min.x + 1;
    height = dw.max.y - dw.min.y + 1;

    rPixels.resizeErase (height, width);
    gPixels.resizeErase (height, width);
    zPixels.resizeErase (height, width);

    FrameBuffer frameBuffer;

    frameBuffer.insert ("R",					// name
			Slice (IMF::HALF,			// type
			       (char *) (&rPixels[0][0] -	// base
					 dw.min.x -
					 dw.min.y * width),
			       sizeof (rPixels[0][0]) * 1,	// xStride
			       sizeof (rPixels[0][0]) * width,	// yStride
			       1, 1,				// x/y sampling
			       0.0));				// fillValue

    frameBuffer.insert ("G",					// name
			Slice (IMF::HALF,			// type
			       (char *) (&gPixels[0][0] -	// base
					 dw.min.x -
					 dw.min.y * width),
			       sizeof (gPixels[0][0]) * 1,	// xStride
			       sizeof (gPixels[0][0]) * width,	// yStride
			       1, 1,				// x/y sampling
			       0.0));				// fillValue

    frameBuffer.insert ("Z",					// name
			Slice (IMF::FLOAT,			// type
			       (char *) (&zPixels[0][0] -	// base
					 dw.min.x -
					 dw.min.y * width),
			       sizeof (zPixels[0][0]) * 1,	 // xStride
			       sizeof (zPixels[0][0]) * width,	// yStride
			       1, 1,				// x/y sampling
			       FLT_MAX));			// fillValue

    file.setFrameBuffer (frameBuffer);
    file.readPixels (dw.min.y, dw.max.y);
}
Exemple #13
0
int
main(int argc, char **argv)
{
short x,y,c,i;
char outfile[300], infile[300];
short num_chars;
int first, last, frame, first_out;
float s, t, tmp;
float red, grn, blu;
short argnm=0;



if (argc <= 4) {
  printf(" usage: %s infiles, outfiles, first_frame, last_frame, first_frame_out\n", argv[0]);
  exit(1);
}

 first = atoi(argv[3]);
 last  = atoi(argv[4]);
 if(argc > 5) {
   first_out = atoi(argv[5]);
 } else {
   first_out=first;
 }

 printf(" processing frames %d to %d to frames %d to %d\n", first, last, first_out, last + first_out - first);


/*******************************************************************************************************************************************************/
/* frame loop: */
   for (frame=first; frame <= last; frame++) {

     sprintf(infile, argv[1], frame);
     num_chars = strlen(infile); /* length of infile string */
     if ((!strcmp(&infile[num_chars-1], "r"))||(!strcmp(&infile[num_chars-1], "R"))) { /* EXR file ending in ".exr" */
      printf(" processing input file %s\n", infile);
     } else { /* not exr */
      printf(" unknown filetype for reading, since extension doesn't end in r, only exr reading supported, infile = %s, aborting\n", outfile);
      exit(1);
     } /* exr or not */

     sprintf(outfile, argv[2], frame + first_out - first);
     num_chars = strlen(outfile); /* length of outfile string */
       if ((!strcmp(&outfile[num_chars-1], "x"))  ||(!strcmp(&outfile[num_chars-1], "X")) || /* DPX floating point file ending in ".dpx" */
           (!strcmp(&outfile[num_chars-3], "x32"))||(!strcmp(&outfile[num_chars-3], "X32"))) { /* DPX32 */
        printf(" processing output file %s\n", outfile);
       } else { /* not exr */
        printf(" unknown filetype for writing, since extension doesn't end in x or x32, only dpx float writing supported, outfile = %s, aborting\n", outfile);
        exit(1);
       } /* exr or not */

    RgbaInputFile file (infile, 1 );

    Box2i dw = file.dataWindow();

    h_reso = dw.max.x - dw.min.x + 1;
    v_reso = dw.max.y - dw.min.y + 1;
    half_float_pixels.resizeErase (v_reso, h_reso);

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

    if (pixels == NULL) { pixels = (float *) malloc(h_reso * v_reso * 12); /* 4-bytes/float * 3-colors */ }


    for(y=0; y< v_reso; y++) {
      for(x=0; x< h_reso; x++) {
        pixels[(0*v_reso + y) * h_reso + x] = half_float_pixels[y][x].r;
        pixels[(1*v_reso + y) * h_reso + x] = half_float_pixels[y][x].g;
        pixels[(2*v_reso + y) * h_reso + x] = half_float_pixels[y][x].b;
      } /* x */
    } /* y */

    dpx_write_float(outfile, pixels, h_reso, v_reso);

    printf(" finished writing %s at x_reso = %d y_reso = %d\n", outfile, h_reso, v_reso);

 } /* frame loop */

} /* main */
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
{
    char *exrFileName;
    double *mxData;
    int width = 0;
    int height = 0;
    int nSlices = 0;
    
    if (nrhs != 1 || !mxIsChar(prhs[0])) {
        mexErrMsgTxt("Usage: ReadMultichannelEXR('exrFile')\n");
    }
    
    // read the exr file with OpenEXR general interface
    exrFileName = mxArrayToString(prhs[0]);
    InputFile file (exrFileName);
    
    // query general file properties
    Box2i dw = file.header().dataWindow();
    width = dw.max.x - dw.min.x + 1;
    height = dw.max.y - dw.min.y + 1;
    
    const ChannelList &channels = file.header().channels();
    for (ChannelList::ConstIterator iter = channels.begin();
    iter != channels.end();
    ++iter) {
        nSlices++;
    }
    
    mexPrintf("Read \"%s\": width=%d height=%d nSlices=%d\n",
            exrFileName, width, height, nSlices);
    mxFree(exrFileName);
    
    // return a struct with info about image slices
    mwSize nDims = 2;
    mwSize infoDims[] = {1, 0};
    infoDims[1] = nSlices;
    const char* fieldNames[] = {"name", "pixelType",
    "xSampling", "ySampling", "isLinear"};
    int nFields = sizeof(fieldNames)/sizeof(fieldNames[0]);
    plhs[0] = mxCreateStructArray(nDims, infoDims, nFields, fieldNames);
    
    // return a double array with size [height width nSlices]
    nDims = 3;
    mwSize dataDims[] = {0, 0, 0};
    dataDims[0] = height;
    dataDims[1] = width;
    dataDims[2] = nSlices;
    plhs[1] = mxCreateNumericArray(nDims, dataDims, mxDOUBLE_CLASS, mxREAL);
    if (NULL == plhs[1]) {
        mexPrintf("Could not allocate image array of size [%d %d %d]\n",
                dataDims[0], dataDims[1], dataDims[2]);
        return;
    }
    double* data = mxGetPr(plhs[1]);
    
    // fill in info struct and data array
    int channelIndex = 0;
    for (ChannelList::ConstIterator iter = channels.begin(); iter != channels.end(); ++iter) {
        const Channel &channel = iter.channel();
        
        // fill in info struct for this channel
        mxSetField(plhs[0], channelIndex, "name", mxCreateString(iter.name()));
        mxSetField(plhs[0], channelIndex, "xSampling", mxCreateDoubleScalar((double)channel.xSampling));
        mxSetField(plhs[0], channelIndex, "ySampling", mxCreateDoubleScalar((double)channel.ySampling));
        mxSetField(plhs[0], channelIndex, "isLinear", mxCreateLogicalScalar((mxLogical)channel.pLinear));
        
        // fill in a slice of the data matrix for this channel
        //  memory allocation depends on slice pixel type
        mxArray* typeName = NULL;
        FrameBuffer frameBuffer;
        switch (channel.type) {
            case UINT:{
                typeName = mxCreateString("UINT");
                
                // copy slice data from file to a frame buffer
                Array2D<MATLAB_UINT32> slicePixels;
                slicePixels.resizeErase(height, width);
                frameBuffer.insert(iter.name(),
                        Slice(HALF,
                        (char *)(&slicePixels[0][0] - dw.min.x - dw.min.y * width),
                        sizeof(slicePixels[0][0]) * 1,
                        sizeof(slicePixels[0][0]) * width,
                        channel.xSampling,
                        channel.ySampling,
                        0.0));
                file.setFrameBuffer (frameBuffer);
                file.readPixels (dw.min.y, dw.max.y);
                
                // copy slice data from frame buffer to data array
                for (int i = 0; i < height; i++) {
                    for (int j = 0; j < width; j++) {
                        data[M3I(height, width, i, j, channelIndex)] = slicePixels[i][j];
                    }
                }
                
                break;
            }
            
            case HALF:{
                typeName = mxCreateString("HALF");
                
                // copy slice data from file to a frame buffer
                Array2D<half> slicePixels;
                slicePixels.resizeErase(height, width);
                frameBuffer.insert(iter.name(),
                        Slice(HALF,
                        (char *)(&slicePixels[0][0] - dw.min.x - dw.min.y * width),
                        sizeof(slicePixels[0][0]) * 1,
                        sizeof(slicePixels[0][0]) * width,
                        channel.xSampling,
                        channel.ySampling,
                        0.0));
                file.setFrameBuffer (frameBuffer);
                file.readPixels (dw.min.y, dw.max.y);
                
                // copy slice data from frame buffer to data array
                for (int i = 0; i < height; i++) {
                    for (int j = 0; j < width; j++) {
                        data[M3I(height, width, i, j, channelIndex)] = slicePixels[i][j];
                    }
                }
                
                break;
            }
            
            case FLOAT:{
                typeName = mxCreateString("FLOAT");
                
                // copy slice data from file to a frame buffer
                Array2D<half> slicePixels;
                slicePixels.resizeErase(height, width);
                frameBuffer.insert(iter.name(),
                        Slice(HALF,
                        (char *)(&slicePixels[0][0] - dw.min.x - dw.min.y * width),
                        sizeof(slicePixels[0][0]) * 1,
                        sizeof(slicePixels[0][0]) * width,
                        channel.xSampling,
                        channel.ySampling,
                        0.0));
                file.setFrameBuffer (frameBuffer);
                file.readPixels (dw.min.y, dw.max.y);
                
                // copy slice data from frame buffer to data array
                for (int i = 0; i < height; i++) {
                    for (int j = 0; j < width; j++) {
                        data[M3I(height, width, i, j, channelIndex)] = slicePixels[i][j];
                    }
                }
                
                break;
            }
            
            default:{
                typeName = mxCreateString("UNKNOWN");
                break;
            }
        }
        mxSetField(plhs[0], channelIndex, "pixelType",  typeName);
        
        channelIndex++;
        
        //mexPrintf("  channel \"%s\": type=%d xSampling=%d ySampling=%d, isLinear=%d\n",
        //        iter.name(), channel.type,
        //        channel.xSampling, channel.ySampling, channel.pLinear);
    }
}