Jump to content

  • Log In with Google      Sign In   
  • Create Account


#ActualChris_F

Posted 30 December 2012 - 05:39 AM

I wrote a small program to test the conversion from HDR RGB to LogLUV. It takes a HDR image (.EXR) and then converts the floating point RGB pixel value to an 32-bit LogLUV value. It then converts it back to floating point RGB and saves the image to a new EXR file.

 

For some reason, I know not why, it is not working.

 

#include <iostream>

#include <FreeImage.h>

#include <glm/glm.hpp>


using namespace glm;


FIBITMAP* LoadImage(const char* filename)

{

    FREE_IMAGE_FORMAT fif = FIF_UNKNOWN;

    fif = FreeImage_GetFileType(filename);

    if(fif == FIF_UNKNOWN)

    {

        fif = FreeImage_GetFIFFromFilename(filename);

    }

    if((fif != FIF_UNKNOWN) && FreeImage_FIFSupportsReading(fif))

    {

        return FreeImage_Load(fif, filename);

    }

    return NULL;

}


// M matrix, for encoding

const mat3 M(

    0.2209, 0.3390, 0.4184,

    0.1138, 0.6780, 0.7319,

    0.0102, 0.1130, 0.2969

);


// Inverse M matrix, for decoding

const mat3 InverseM(

    6.0014, -2.7008, -1.7996,

    -1.3320,  3.1029, -5.7721,

    0.3008, -1.0882,  5.6268

);


vec4 LogLuvEncode(vec3 vRGB)

{

    vec4 vResult;

    vec3 Xp_Y_XYZp = vRGB * M;

    Xp_Y_XYZp = glm::max(Xp_Y_XYZp, vec3(1e-6, 1e-6, 1e-6));

    vResult.x = Xp_Y_XYZp.x / Xp_Y_XYZp.z;

    vResult.y = Xp_Y_XYZp.y / Xp_Y_XYZp.z;

    float Le = 2 * glm::log2(Xp_Y_XYZp.y) + 127;

    vResult.w = glm::fract(Le);

    vResult.z = (Le - (glm::floor(vResult.w*255.0f))/255.0f)/255.0f;

    return vResult;

}


vec3 LogLuvDecode(vec4 vLogLuv)

{

    float Le = vLogLuv.z * 255 + vLogLuv.w;

    vec3 Xp_Y_XYZp;

    Xp_Y_XYZp.y = glm::exp2((Le - 127) / 2);

    Xp_Y_XYZp.z = Xp_Y_XYZp.y / vLogLuv.y;

    Xp_Y_XYZp.x = vLogLuv.x * Xp_Y_XYZp.z;

    vec3 vRGB = Xp_Y_XYZp * InverseM;

    return glm::max(vRGB, 0);

}


int main()

{

    FIBITMAP* dib = LoadImage("in.exr");


    int width = FreeImage_GetWidth(dib);

    int height = FreeImage_GetHeight(dib);


    FIBITMAP* dib2 = FreeImage_AllocateT(FIT_RGBF, width, height);


    for(int y = 0; y < height; y++)

    {

        FIRGBF* InputPixel = (FIRGBF*)FreeImage_GetScanLine(dib, y);

        FIRGBF* OutputPixel = (FIRGBF*)FreeImage_GetScanLine(dib2, y);


        for(int x = 0; x < width; x++)

        {

            vec3 input(InputPixel[x].red, InputPixel[x].green, InputPixel[x].blue);


            vec4 enc = LogLuvEncode(input);


            BYTE r = enc.r * 255.0;

            BYTE g = enc.g * 255.0;

            BYTE b = enc.b * 255.0;

            BYTE a = enc.a * 255.0;


            vec3 dec = LogLuvDecode(vec4(r,g,b,a) / 255.0);


            OutputPixel[x].red = dec.r;

            OutputPixel[x].green = dec.g;

            OutputPixel[x].blue = dec.b;

        }

    }


    FreeImage_Save(FIF_EXR, dib2, "out.exr");

}

 

This doesn't work.

 

#include <iostream>

#include <FreeImage.h>

#include <glm/glm.hpp>


using namespace glm;


FIBITMAP* LoadImage(const char* filename)

{

    FREE_IMAGE_FORMAT fif = FIF_UNKNOWN;

    fif = FreeImage_GetFileType(filename);

    if(fif == FIF_UNKNOWN)

    {

        fif = FreeImage_GetFIFFromFilename(filename);

    }

    if((fif != FIF_UNKNOWN) && FreeImage_FIFSupportsReading(fif))

    {

        return FreeImage_Load(fif, filename);

    }

    return NULL;

}


// M matrix, for encoding

const mat3 M(

    0.2209, 0.3390, 0.4184,

    0.1138, 0.6780, 0.7319,

    0.0102, 0.1130, 0.2969

);


// Inverse M matrix, for decoding

const mat3 InverseM(

    6.0014, -2.7008, -1.7996,

    -1.3320,  3.1029, -5.7721,

    0.3008, -1.0882,  5.6268

);


vec4 LogLuvEncode(vec3 vRGB)

{

    vec4 vResult;

    vec3 Xp_Y_XYZp = vRGB * M;

    Xp_Y_XYZp = glm::max(Xp_Y_XYZp, vec3(1e-6, 1e-6, 1e-6));

    vResult.x = Xp_Y_XYZp.x / Xp_Y_XYZp.z;

    vResult.y = Xp_Y_XYZp.y / Xp_Y_XYZp.z;

    float Le = 2 * glm::log2(Xp_Y_XYZp.y) + 127;

    vResult.w = glm::fract(Le);

    vResult.z = (Le - (glm::floor(vResult.w*255.0f))/255.0f)/255.0f;

    return vResult;

}


vec3 LogLuvDecode(vec4 vLogLuv)

{

    float Le = vLogLuv.z * 255 + vLogLuv.w;

    vec3 Xp_Y_XYZp;

    Xp_Y_XYZp.y = glm::exp2((Le - 127) / 2);

    Xp_Y_XYZp.z = Xp_Y_XYZp.y / vLogLuv.y;

    Xp_Y_XYZp.x = vLogLuv.x * Xp_Y_XYZp.z;

    vec3 vRGB = Xp_Y_XYZp * InverseM;

    return glm::max(vRGB, 0);

}


int main()

{

    FIBITMAP* dib = LoadImage("in.exr");


    int width = FreeImage_GetWidth(dib);

    int height = FreeImage_GetHeight(dib);


    FIBITMAP* dib2 = FreeImage_AllocateT(FIT_RGBF, width, height);


    for(int y = 0; y < height; y++)

    {

        FIRGBF* InputPixel = (FIRGBF*)FreeImage_GetScanLine(dib, y);

        FIRGBF* OutputPixel = (FIRGBF*)FreeImage_GetScanLine(dib2, y);


        for(int x = 0; x < width; x++)

        {

            vec3 input(InputPixel[x].red, InputPixel[x].green, InputPixel[x].blue);


            vec4 enc = LogLuvEncode(input);


            vec3 dec = LogLuvDecode(enc);


            OutputPixel[x].red = dec.r;

            OutputPixel[x].green = dec.g;

            OutputPixel[x].blue = dec.b;

        }

    }


    FreeImage_Save(FIF_EXR, dib2, "out.exr");

}

 

However, this does.


#1Chris_F

Posted 30 December 2012 - 05:34 AM

I wrote a small program to test the conversion from HDR RGB to LogLUV. It takes a HDR image (.EXR) and then converts the floating point RGB pixel value to an 32-bit LogLUV value. It then converts it back to floating point RGB and saves the image to a new EXR file.

 

For some reason, I know not why, it is not working.

 

#include <iostream>

#include <FreeImage.h>

#include <glm/glm.hpp>


using namespace glm;


FIBITMAP* LoadImage(const char* filename)

{

    FREE_IMAGE_FORMAT fif = FIF_UNKNOWN;

    fif = FreeImage_GetFileType(filename);

    if(fif == FIF_UNKNOWN)

    {

        fif = FreeImage_GetFIFFromFilename(filename);

    }

    if((fif != FIF_UNKNOWN) && FreeImage_FIFSupportsReading(fif))

    {

        return FreeImage_Load(fif, filename);

    }

    return NULL;

}


// M matrix, for encoding

const mat3 M(

    0.2209, 0.3390, 0.4184,

    0.1138, 0.6780, 0.7319,

    0.0102, 0.1130, 0.2969

);


// Inverse M matrix, for decoding

const mat3 InverseM(

    6.0014, -2.7008, -1.7996,

    -1.3320,  3.1029, -5.7721,

    0.3008, -1.0882,  5.6268

);


vec4 LogLuvEncode(vec3 vRGB)

{

    vec4 vResult;

    vec3 Xp_Y_XYZp = vRGB * M;

    Xp_Y_XYZp = glm::max(Xp_Y_XYZp, vec3(1e-6, 1e-6, 1e-6));

    vResult.x = Xp_Y_XYZp.x / Xp_Y_XYZp.z;

    vResult.y = Xp_Y_XYZp.y / Xp_Y_XYZp.z;

    float Le = 2 * glm::log2(Xp_Y_XYZp.y) + 127;

    vResult.w = glm::fract(Le);

    vResult.z = (Le - (glm::floor(vResult.w*255.0f))/255.0f)/255.0f;

    return vResult;

}


vec3 LogLuvDecode(vec4 vLogLuv)

{

    float Le = vLogLuv.z * 255 + vLogLuv.w;

    vec3 Xp_Y_XYZp;

    Xp_Y_XYZp.y = glm::exp2((Le - 127) / 2);

    Xp_Y_XYZp.z = Xp_Y_XYZp.y / vLogLuv.y;

    Xp_Y_XYZp.x = vLogLuv.x * Xp_Y_XYZp.z;

    vec3 vRGB = Xp_Y_XYZp * InverseM;

    return glm::max(vRGB, 0);

}


int main()

{

    FIBITMAP* dib = LoadImage("in.exr");


    int width = FreeImage_GetWidth(dib);

    int height = FreeImage_GetHeight(dib);


    FIBITMAP* dib2 = FreeImage_AllocateT(FIT_RGBF, width, height);


    for(int y = 0; y < height; y++)

    {

        FIRGBF* InputPixel = (FIRGBF*)FreeImage_GetScanLine(dib, y);

        FIRGBF* OutputPixel = (FIRGBF*)FreeImage_GetScanLine(dib2, y);


        for(int x = 0; x < width; x++)

        {

            vec3 input(InputPixel[x].red, InputPixel[x].green, InputPixel[x].blue);


            vec4 enc = LogLuvEncode(input);


            BYTE r = enc.r * 255.0;

            BYTE g = enc.g * 255.0;

            BYTE b = enc.b * 255.0;

            BYTE a = enc.a * 255.0;


            vec3 dec = LogLuvDecode(vec4(r,g,b,a) / 255.0);


            OutputPixel[x].red = dec.r;

            OutputPixel[x].green = dec.g;

            OutputPixel[x].blue = dec.b;

        }

    }


    FreeImage_Save(FIF_EXR, dib2, "out.exr");

}#include <iostream>

#include <FreeImage.h>

#include <glm/glm.hpp>


using namespace glm;


FIBITMAP* LoadImage(const char* filename)

{

    FREE_IMAGE_FORMAT fif = FIF_UNKNOWN;

    fif = FreeImage_GetFileType(filename);

    if(fif == FIF_UNKNOWN)

    {

        fif = FreeImage_GetFIFFromFilename(filename);

    }

    if((fif != FIF_UNKNOWN) && FreeImage_FIFSupportsReading(fif))

    {

        return FreeImage_Load(fif, filename);

    }

    return NULL;

}


// M matrix, for encoding

const mat3 M(

    0.2209, 0.3390, 0.4184,

    0.1138, 0.6780, 0.7319,

    0.0102, 0.1130, 0.2969

);


// Inverse M matrix, for decoding

const mat3 InverseM(

    6.0014, -2.7008, -1.7996,

    -1.3320,  3.1029, -5.7721,

    0.3008, -1.0882,  5.6268

);


vec4 LogLuvEncode(vec3 vRGB)

{

    vec4 vResult;

    vec3 Xp_Y_XYZp = vRGB * M;

    Xp_Y_XYZp = glm::max(Xp_Y_XYZp, vec3(1e-6, 1e-6, 1e-6));

    vResult.x = Xp_Y_XYZp.x / Xp_Y_XYZp.z;

    vResult.y = Xp_Y_XYZp.y / Xp_Y_XYZp.z;

    float Le = 2 * glm::log2(Xp_Y_XYZp.y) + 127;

    vResult.w = glm::fract(Le);

    vResult.z = (Le - (glm::floor(vResult.w*255.0f))/255.0f)/255.0f;

    return vResult;

}


vec3 LogLuvDecode(vec4 vLogLuv)

{

    float Le = vLogLuv.z * 255 + vLogLuv.w;

    vec3 Xp_Y_XYZp;

    Xp_Y_XYZp.y = glm::exp2((Le - 127) / 2);

    Xp_Y_XYZp.z = Xp_Y_XYZp.y / vLogLuv.y;

    Xp_Y_XYZp.x = vLogLuv.x * Xp_Y_XYZp.z;

    vec3 vRGB = Xp_Y_XYZp * InverseM;

    return glm::max(vRGB, 0);

}


int main()

{

    FIBITMAP* dib = LoadImage("in.exr");


    int width = FreeImage_GetWidth(dib);

    int height = FreeImage_GetHeight(dib);


    FIBITMAP* dib2 = FreeImage_AllocateT(FIT_RGBF, width, height);


    for(int y = 0; y < height; y++)

    {

        FIRGBF* InputPixel = (FIRGBF*)FreeImage_GetScanLine(dib, y);

        FIRGBF* OutputPixel = (FIRGBF*)FreeImage_GetScanLine(dib2, y);


        for(int x = 0; x < width; x++)

        {

            vec3 input(InputPixel[x].red, InputPixel[x].green, InputPixel[x].blue);


            vec4 enc = LogLuvEncode(input);


            BYTE r = enc.r * 255.0;

            BYTE g = enc.g * 255.0;

            BYTE b = enc.b * 255.0;

            BYTE a = enc.a * 255.0;


            vec3 dec = LogLuvDecode(vec4(r,g,b,a) / 255.0);


            OutputPixel[x].red = dec.r;

            OutputPixel[x].green = dec.g;

            OutputPixel[x].blue = dec.b;

        }

    }


    FreeImage_Save(FIF_EXR, dib2, "out.exr");

}

 

This doesn't work.

 

#include <iostream>

#include <FreeImage.h>

#include <glm/glm.hpp>


using namespace glm;


FIBITMAP* LoadImage(const char* filename)

{

    FREE_IMAGE_FORMAT fif = FIF_UNKNOWN;

    fif = FreeImage_GetFileType(filename);

    if(fif == FIF_UNKNOWN)

    {

        fif = FreeImage_GetFIFFromFilename(filename);

    }

    if((fif != FIF_UNKNOWN) && FreeImage_FIFSupportsReading(fif))

    {

        return FreeImage_Load(fif, filename);

    }

    return NULL;

}


// M matrix, for encoding

const mat3 M(

    0.2209, 0.3390, 0.4184,

    0.1138, 0.6780, 0.7319,

    0.0102, 0.1130, 0.2969

);


// Inverse M matrix, for decoding

const mat3 InverseM(

    6.0014, -2.7008, -1.7996,

    -1.3320,  3.1029, -5.7721,

    0.3008, -1.0882,  5.6268

);


vec4 LogLuvEncode(vec3 vRGB)

{

    vec4 vResult;

    vec3 Xp_Y_XYZp = vRGB * M;

    Xp_Y_XYZp = glm::max(Xp_Y_XYZp, vec3(1e-6, 1e-6, 1e-6));

    vResult.x = Xp_Y_XYZp.x / Xp_Y_XYZp.z;

    vResult.y = Xp_Y_XYZp.y / Xp_Y_XYZp.z;

    float Le = 2 * glm::log2(Xp_Y_XYZp.y) + 127;

    vResult.w = glm::fract(Le);

    vResult.z = (Le - (glm::floor(vResult.w*255.0f))/255.0f)/255.0f;

    return vResult;

}


vec3 LogLuvDecode(vec4 vLogLuv)

{

    float Le = vLogLuv.z * 255 + vLogLuv.w;

    vec3 Xp_Y_XYZp;

    Xp_Y_XYZp.y = glm::exp2((Le - 127) / 2);

    Xp_Y_XYZp.z = Xp_Y_XYZp.y / vLogLuv.y;

    Xp_Y_XYZp.x = vLogLuv.x * Xp_Y_XYZp.z;

    vec3 vRGB = Xp_Y_XYZp * InverseM;

    return glm::max(vRGB, 0);

}


int main()

{

    FIBITMAP* dib = LoadImage("in.exr");


    int width = FreeImage_GetWidth(dib);

    int height = FreeImage_GetHeight(dib);


    FIBITMAP* dib2 = FreeImage_AllocateT(FIT_RGBF, width, height);


    for(int y = 0; y < height; y++)

    {

        FIRGBF* InputPixel = (FIRGBF*)FreeImage_GetScanLine(dib, y);

        FIRGBF* OutputPixel = (FIRGBF*)FreeImage_GetScanLine(dib2, y);


        for(int x = 0; x < width; x++)

        {

            vec3 input(InputPixel[x].red, InputPixel[x].green, InputPixel[x].blue);


            vec4 enc = LogLuvEncode(input);


            BYTE r = enc.r * 255.0;

            BYTE g = enc.g * 255.0;

            BYTE b = enc.b * 255.0;

            BYTE a = enc.a * 255.0;


            vec3 dec = LogLuvDecode(vec4(r,g,b,a) / 255.0);


            OutputPixel[x].red = dec.r;

            OutputPixel[x].green = dec.g;

            OutputPixel[x].blue = dec.b;

        }

    }


    FreeImage_Save(FIF_EXR, dib2, "out.exr");

}#include <iostream>

#include <FreeImage.h>

#include <glm/glm.hpp>


using namespace glm;


FIBITMAP* LoadImage(const char* filename)

{

    FREE_IMAGE_FORMAT fif = FIF_UNKNOWN;

    fif = FreeImage_GetFileType(filename);

    if(fif == FIF_UNKNOWN)

    {

        fif = FreeImage_GetFIFFromFilename(filename);

    }

    if((fif != FIF_UNKNOWN) && FreeImage_FIFSupportsReading(fif))

    {

        return FreeImage_Load(fif, filename);

    }

    return NULL;

}


// M matrix, for encoding

const mat3 M(

    0.2209, 0.3390, 0.4184,

    0.1138, 0.6780, 0.7319,

    0.0102, 0.1130, 0.2969

);


// Inverse M matrix, for decoding

const mat3 InverseM(

    6.0014, -2.7008, -1.7996,

    -1.3320,  3.1029, -5.7721,

    0.3008, -1.0882,  5.6268

);


vec4 LogLuvEncode(vec3 vRGB)

{

    vec4 vResult;

    vec3 Xp_Y_XYZp = vRGB * M;

    Xp_Y_XYZp = glm::max(Xp_Y_XYZp, vec3(1e-6, 1e-6, 1e-6));

    vResult.x = Xp_Y_XYZp.x / Xp_Y_XYZp.z;

    vResult.y = Xp_Y_XYZp.y / Xp_Y_XYZp.z;

    float Le = 2 * glm::log2(Xp_Y_XYZp.y) + 127;

    vResult.w = glm::fract(Le);

    vResult.z = (Le - (glm::floor(vResult.w*255.0f))/255.0f)/255.0f;

    return vResult;

}


vec3 LogLuvDecode(vec4 vLogLuv)

{

    float Le = vLogLuv.z * 255 + vLogLuv.w;

    vec3 Xp_Y_XYZp;

    Xp_Y_XYZp.y = glm::exp2((Le - 127) / 2);

    Xp_Y_XYZp.z = Xp_Y_XYZp.y / vLogLuv.y;

    Xp_Y_XYZp.x = vLogLuv.x * Xp_Y_XYZp.z;

    vec3 vRGB = Xp_Y_XYZp * InverseM;

    return glm::max(vRGB, 0);

}


int main()

{

    FIBITMAP* dib = LoadImage("in.exr");


    int width = FreeImage_GetWidth(dib);

    int height = FreeImage_GetHeight(dib);


    FIBITMAP* dib2 = FreeImage_AllocateT(FIT_RGBF, width, height);


    for(int y = 0; y < height; y++)

    {

        FIRGBF* InputPixel = (FIRGBF*)FreeImage_GetScanLine(dib, y);

        FIRGBF* OutputPixel = (FIRGBF*)FreeImage_GetScanLine(dib2, y);


        for(int x = 0; x < width; x++)

        {

            vec3 input(InputPixel[x].red, InputPixel[x].green, InputPixel[x].blue);


            vec4 enc = LogLuvEncode(input);


            vec3 dec = LogLuvDecode(enc);


            OutputPixel[x].red = dec.r;

            OutputPixel[x].green = dec.g;

            OutputPixel[x].blue = dec.b;

        }

    }


    FreeImage_Save(FIF_EXR, dib2, "out.exr");

}

 

However, this does.


PARTNERS