Beispiel #1
0
TEST(EXR, BasicRoundTrip) {
   int width = 289;
   int height = 1 + 65536 / width;

   float *buf = new float[width * height];
   for (int i = 0; i < 65536; ++i) {
     FP16 half;
     half.u = i;
     buf[i] = half_to_float_full(half).f;
   }
   for (int i = 65536; i < width * height; ++i)
     buf[i] = 0;

   EXRImage image;
   image.num_channels = 1;
   const char *channels[] = { "R" };
   image.channel_names = channels;
   unsigned char *images[] = { (unsigned char *)buf };
   image.images = images;
   int pixel_types[] = { TINYEXR_PIXELTYPE_HALF };
   image.pixel_types = pixel_types;
   image.width = width;
   image.height = height;

   const char *err = nullptr;
   EXPECT_EQ(0, SaveMultiChannelEXRToFile(&image, "test.exr", &err)) << err;

   EXRImage readImage;
   EXPECT_EQ(0, LoadMultiChannelEXRFromFile(&readImage, "test.exr", &err))
       << err;

   CompareImages(image, readImage, false);
}
Beispiel #2
0
TEST(EXR, Randoms) {
   int width = 1024;
   int height = 1024;

   RNG rng;
   float *buf = new float[4 * width * height];
   for (int i = 0; i < 4 * width * height; ++i) {
     buf[i] = -20 + 20. * rng.UniformFloat();
   }

   EXRImage image;
   image.num_channels = 4;
   const char *channels[] = { "B", "G", "R", "A" };
   image.channel_names = channels;
   unsigned char *images[] = { (unsigned char *)buf,
                               (unsigned char *)(buf + width * height),
                               (unsigned char *)(buf + 2 * width * height),
                               (unsigned char *)(buf + 3 * width * height) };
   image.images = images;
   int pixel_types[] = { TINYEXR_PIXELTYPE_HALF, TINYEXR_PIXELTYPE_HALF,
                         TINYEXR_PIXELTYPE_HALF, TINYEXR_PIXELTYPE_HALF };
   image.pixel_types = pixel_types;
   image.width = width;
   image.height = height;

   const char *err = nullptr;
   EXPECT_EQ(0, SaveMultiChannelEXRToFile(&image, "test.exr", &err)) << err;

   EXRImage readImage;
   EXPECT_EQ(0, LoadMultiChannelEXRFromFile(&readImage, "test.exr", &err))
       << err;

   CompareImages(image, readImage, true);
}
Beispiel #3
0
static RGBSpectrum *ReadImageEXR(const std::string &name, int *width,
                                 int *height) {
    EXRImage img;
    const char *err = nullptr;
    if (ParseMultiChannelEXRHeaderFromFile(&img, name.c_str(), &err) != 0) {
        Error("Unable to read \"%s\": %s", name.c_str(), err);
        return nullptr;
    }
    for (int i = 0; i < img.num_channels; ++i) {
        if (img.requested_pixel_types[i] == TINYEXR_PIXELTYPE_HALF)
            img.requested_pixel_types[i] = TINYEXR_PIXELTYPE_FLOAT;
    }
    if (LoadMultiChannelEXRFromFile(&img, name.c_str(), &err) != 0) {
        Error("Unable to read \"%s\": %s", name.c_str(), err);
        return nullptr;
    }

    *width = img.width;
    *height = img.height;

    int idxR = -1, idxG = -1, idxB = -1;
    for (int c = 0; c < img.num_channels; c++) {
        if (strcmp(img.channel_names[c], "R") == 0) {
            idxR = c;
        } else if (strcmp(img.channel_names[c], "G") == 0) {
            idxG = c;
        } else if (strcmp(img.channel_names[c], "B") == 0) {
            idxB = c;
        }
    }

    RGBSpectrum *ret = new RGBSpectrum[img.width * img.height];
    int offset = 0;
    for (int y = 0; y < img.height; ++y) {
        for (int x = 0; x < img.width; ++x, ++offset) {
            if (img.num_channels == 1)
                ret[offset] =
                    convert(img.images[0], offset, img.pixel_types[0]);
            else {
                Float rgb[3] = {
                    convert(img.images[idxR], offset, img.pixel_types[idxR]),
                    convert(img.images[idxG], offset, img.pixel_types[idxG]),
                    convert(img.images[idxB], offset, img.pixel_types[idxB])
                };
                ret[offset] = RGBSpectrum::FromRGB(rgb);
            }
        }
    }
    FreeEXRImage(&img);

    return ret;
}
Beispiel #4
0
ImageSourceFileTinyExr::ImageSourceFileTinyExr( DataSourceRef dataSource, ImageSource::Options /*options*/ )
{
	mExrImage.reset( new EXRImage );
	const char *error;

	InitEXRImage( mExrImage.get() );

	int status = 0;
	if( dataSource->isFilePath() ) {
		status = ParseMultiChannelEXRHeaderFromFile( mExrImage.get(), dataSource->getFilePath().string().c_str(), &error );
		if( status != 0 )
			throw ImageIoExceptionFailedLoadTinyExr( string( "Failed to parse OpenEXR header; Error message: " ) + error );
		status = LoadMultiChannelEXRFromFile( mExrImage.get(), dataSource->getFilePath().string().c_str(), &error );
		if( status != 0 )
			throw ImageIoExceptionFailedLoadTinyExr( string( "Failed to parse OpenEXR file; Error message: " ) + error );
	}
	else {
		BufferRef buffer = dataSource->getBuffer();
		
		status = ParseMultiChannelEXRHeaderFromMemory( mExrImage.get(), (const unsigned char*)buffer->getData(), &error );
		if( status != 0 )
			throw ImageIoExceptionFailedLoadTinyExr( string( "Failed to parse OpenEXR header; Error message: " ) + error );
		status = LoadMultiChannelEXRFromMemory( mExrImage.get(), (const unsigned char*)buffer->getData(), &error );
		if( status != 0 )
			throw ImageIoExceptionFailedLoadTinyExr( string( "Failed to parse OpenEXR file; Error message: " ) + error );
	}

	// verify that the channels are all the same size; currently we don't support variably sized channels
	int pixelType = mExrImage->pixel_types[0];
	for( int c = 1; c < mExrImage->num_channels; ++c ) {
		if( pixelType != mExrImage->pixel_types[c] )
			throw ImageIoExceptionFailedLoadTinyExr( "TinyExr: heterogneous channel data types not supported" );
	}

	switch( pixelType ) {
		case TINYEXR_PIXELTYPE_HALF:
			setDataType( ImageIo::FLOAT16 );
		break;
		case TINYEXR_PIXELTYPE_FLOAT:
			setDataType( ImageIo::FLOAT32 );
		break;
		default:
			throw ImageIoExceptionFailedLoadTinyExr( "TinyExr: Unknown data type" );
		break;
	}

	setSize( mExrImage->width, mExrImage->height );

	switch( mExrImage->num_channels ) {
		case 3:
			setColorModel( ImageIo::CM_RGB );
			setChannelOrder( ImageIo::ChannelOrder::RGB );
		break;
		case 4:
			setColorModel( ImageIo::CM_RGB );
			setChannelOrder( ImageIo::ChannelOrder::RGBA );
		break;
		default:
			throw ImageIoExceptionFailedLoadTinyExr( "TinyExr: Unsupported number of channels (" + to_string( mExrImage->num_channels ) + ")" );
	}
}
Beispiel #5
0
/* The gateway function */
void mexFunction( int nlhs, mxArray *plhs[],
                  int nrhs, const mxArray *prhs[])
{
    /* check for proper number of arguments */
    if(nrhs != 1) {
        mexErrMsgIdAndTxt("HDRToolbox:write_exr:nrhs", "One input is required.");
    }
    
    char *nameFile;
    mwSize buflen;
    int status;    
    buflen = mxGetN(prhs[0])*sizeof(mxChar)+1;
    nameFile = (char*) mxMalloc(buflen);
    
    /* Copy the string data into buf. */ 
    status = mxGetString(prhs[0], nameFile, buflen);
    
    /* call the computational routine */
    EXRImage image;
    InitEXRImage(&image);

    const char* err;
    int ret = ParseMultiChannelEXRHeaderFromFile(&image, nameFile, &err);
    if (ret != 0) {
        printf("Parse EXR error: %s\n", err);
        return;
    }

    int width = image.width;
    int height = image.height;
    int channels = image.num_channels;

    //Allocate into memory

    mwSize dims[3];
    dims[0] = height;
    dims[1] = width;
    dims[2] = channels;

    plhs[0] = mxCreateNumericArray(channels, dims, mxDOUBLE_CLASS, mxREAL);
    double *outMatrix = mxGetPr(plhs[0]);

    for (int i = 0; i < image.num_channels; i++) {
        if (image.pixel_types[i] == TINYEXR_PIXELTYPE_HALF) {
            image.requested_pixel_types[i] = TINYEXR_PIXELTYPE_FLOAT;
        }
    }
    
    ret = LoadMultiChannelEXRFromFile(&image, nameFile, &err);
    
    if (ret != 0) {
        printf("Load EXR error: %s\n", err);
        return;
    }
    
    float **images = (float**) image.images;
    int nPixels = width * height;
    int nPixels2 = nPixels * 2;
    if(channels == 1) {
        nPixels = 0;
        nPixels2 = 0;
    }
    
    if(channels == 2) {
        nPixels2 = 0;
    }
    
    for (int i = 0; i < width; i++){
        for (int j = 0; j < height; j++){
            int index = i * height + j;
            int indexOut = j * width + i;
            
            outMatrix[index    ]        = images[2][indexOut];
            outMatrix[index + nPixels]  = images[1][indexOut];
            outMatrix[index + nPixels2] = images[0][indexOut];
        }
    }
    
    FreeEXRImage(&image);
}