diff options
| author | click <none@none> | 2010-08-27 01:52:05 +0200 | 
|---|---|---|
| committer | click <none@none> | 2010-08-27 01:52:05 +0200 | 
| commit | 7686d6ee57038e848f75130563fc78c1adebc1a2 (patch) | |
| tree | 258a7a6db03e3479a0219ace8cfc3ec3ba53a1be /dep/g3dlite/source/GImage_bayer.cpp | |
| parent | 1d3deae555f0ec523d77875bd5a307ab9bd19742 (diff) | |
Core/Dependency: Upgrade G3d-library to v8.0-release (patched version!)
Note: Due to issues with G3D (normally requiring X11 and the ZIP-library),
the sourcetree version contains a modified version. The applied patch is
commited to the repository for future reference.
--HG--
branch : trunk
Diffstat (limited to 'dep/g3dlite/source/GImage_bayer.cpp')
| -rw-r--r-- | dep/g3dlite/source/GImage_bayer.cpp | 298 | 
1 files changed, 298 insertions, 0 deletions
diff --git a/dep/g3dlite/source/GImage_bayer.cpp b/dep/g3dlite/source/GImage_bayer.cpp new file mode 100644 index 00000000000..3d08e8ade5f --- /dev/null +++ b/dep/g3dlite/source/GImage_bayer.cpp @@ -0,0 +1,298 @@ +/** +  @file GImage_bayer.cpp +  @author Morgan McGuire, http://graphics.cs.williams.edu +  @created 2002-05-27 +  @edited  2006-05-10 + */ +#include "G3D/platform.h" +#include "G3D/GImage.h" + +namespace G3D { + +void GImage::BAYER_G8B8_R8G8_to_Quarter_R8G8B8(int width, int height, const uint8* in, uint8* out) { +    debugAssert(in != out); + +    int halfHeight = height / 2; +    int halfWidth  = width / 2; + +    int dst_off = 0; +    for (int y = 0; y < halfHeight; ++y) { +        for (int x = 0; x < halfWidth; ++x) { +            // GBRG +            int src_off = x*2 + y*2*width; +            out[dst_off] = in[src_off+width]; // red +            out[dst_off+1] = ((int)in[src_off] + (int)in[src_off+width+1])/2; // green +            out[dst_off+2] = in[src_off+1]; // blue             + +            dst_off = dst_off + 3; +        } +    } +} + + +void GImage::Quarter_R8G8B8_to_BAYER_G8B8_R8G8(int inWidth, int inHeight, const uint8* in, uint8* out) { +    // Undo quarter-size Bayer as best we can.  This code isn't very efficient, but it +    // also isn't used very frequently. + +    debugAssert(out != in); + +    int outWidth  = 2 * inWidth; +    int outHeight = 2 * inHeight; + +    for (int y = 0; y < outHeight; ++y) { +        for (int x = 0; x < outWidth; ++x) { +            const Color3uint8* inp = ((const Color3uint8*)in) + ((x/2) + (y/2)* inWidth); +            uint8* outp = out + x + y * outWidth; + +            if (isEven(y)) { +                // GB row +                if (isEven(x)) { +                    // Green +                    *outp = inp->g; +                } else { +                    // Blue +                    *outp = inp->b; +                } +            } else { +                // RG row +                if (isEven(x)) { +                    // Red +                    *outp = inp->r; +                } else { +                    // Green +                    *outp = inp->g; +                } +            } +        } +    } +} + + +/** Applies a 5x5 filter to monochrome image I (wrapping at the boundaries) */ +static uint8 applyFilter( +    const uint8*    I, +    int             x, +    int             y, +    int             w, +    int             h, +    const float     filter[5][5]) { + +    debugAssert(isEven(w)); +    debugAssert(isEven(h)); + +    float sum = 0.0f; +    float denom = 0.0f; + +    for (int dy = 0; dy < 5; ++dy) { +        int offset = ((y + dy + h - 2) % h) * w; + +        for (int dx = 0; dx < 5; ++dx) { +            float f = filter[dy][dx]; +            sum += f * I[((x + dx + w - 2) % w) + offset]; +            denom += f; +        } +    } + +    return (uint8)iClamp(iRound(sum / denom), 0, 255); +} + +//////////////////////////////////////////////////////////////////////////////////////////////// +// +// Bayer conversions +// + +// There are two kinds of rows (GR and BG). +// In each row, there are two kinds of pixels (G/R, B/G). +// We express the four kinds of INPUT pixels as: +//    GRG, GRG, BGB, BGG +// +// There are three kinds of OUTPUT pixels: R, G, B. +// Thus there are nominally 12 different I/O combinations,  +// but several are impulses because needed output at that  +// location *is* the input (e.g., G_GRG and G_BGG). +// +// The following 5x5 row-major filters are named as output_input. + +// Green +static const float G_GRR[5][5] = +{{     0.0f,      0.0f,     -1.0f,      0.0f,      0.0f}, +{     0.0f,      0.0f,      2.0f,      0.0f,      0.0f}, +{    -1.0f,      2.0f,      4.0f,      2.0f,     -1.0f}, +{     0.0f,      0.0f,      2.0f,      0.0f,      0.0f}, +{     0.0f,      0.0f,     -1.0f,      0.0f,      0.0f}}; + +static const float G_BGB[5][5] = +{{     0.0f,      0.0f,     -1.0f,      0.0f,      0.0f}, +{     0.0f,      0.0f,      2.0f,      0.0f,      0.0f}, +{    -1.0f,      2.0f,      4.0f,      2.0f,     -1.0f}, +{     0.0f,      0.0f,      2.0f,      0.0f,      0.0f}, +{     0.0f,      0.0f,     -1.0f,      0.0f,      0.0f}}; + +// Red  +//(the caption in the paper is wrong for this case: +// "R row B column really means R row G column" +static const float R_GRG[5][5] = +{{     0.0f,      0.0f,      0.5f,      0.0f,      0.0f}, +{     0.0f,     -1.0f,      0.0f,     -1.0f,      0.0f}, +{    -1.0f,      4.0f,      5.0f,      4.0f,     -1.0f}, +{     0.0f,     -1.0f,      0.0f,     -1.0f,      0.0f}, +{     0.0f,      0.0f,      0.5f,      0.0f,      0.0f}}; + +static const float R_BGG[5][5] = +{{     0.0f,      0.0f,     -1.0f,      0.0f,      0.0f}, +{     0.0f,     -1.0f,      4.0f,     -1.0f,      0.0f}, +{     0.5f,      0.0f,      5.0f,      0.0f,      0.5f}, +{     0.0f,     -1.0f,      4.0f,     -1.0f,      0.0f}, +{     0.0f,      0.0f,     -1.0f,      0.0f,      0.0f}}; + +static const float R_BGB[5][5] = +{{     0.0f,      0.0f, -3.0f/2.0f,      0.0f,      0.0f}, +{     0.0f,      2.0f,      0.0f,      2.0f,      0.0f}, +{-3.0f/2.0f,      0.0f,      6.0f,      0.0f, -3.0f/2.0f}, +{     0.0f,      2.0f,      0.0f,      2.0f,      0.0f}, +{     0.0f,      0.0f, -3.0f/2.0f,      0.0f,      0.0f}}; + + +// Blue  +//(the caption in the paper is wrong for this case: +// "B row R column really means B row G column") +#define B_BGG R_GRG +#define B_GRG R_BGG +#define B_GRR R_BGB + + +void GImage::BAYER_R8G8_G8B8_to_R8G8B8_MHC(int w, int h, const uint8* in, uint8* _out) { +    debugAssert(in != _out); + +    Color3uint8* out = (Color3uint8*)_out; + +    for (int y = 0; y < h; ++y) { + +        // Row beginning in the input array. +        int offset = y * w; + +        // RG row +        for (int x = 0; x < w; ++x, ++out) { +            // R pixel +            { +                out->r = in[x + offset]; +                out->g = applyFilter(in, x, y, w, h, G_GRR); +                out->b = applyFilter(in, x, y, w, h, B_GRR); +            } +            ++x; ++out; + +            // G pixel +            { +                out->r = applyFilter(in, x, y, w, h, R_GRG); +                out->g = in[x + offset]; +                out->b = applyFilter(in, x, y, w, h, B_GRG); +            } +        } + +        ++y; +        offset += w; + +        // GB row +        for (int x = 0; x < w; ++x, ++out) { +            // G pixel +            { +                out->r = applyFilter(in, x, y, w, h, R_BGG); +                out->g = in[x + offset]; +                out->b = applyFilter(in, x, y, w, h, B_BGG); +            } +            ++x; ++out; + +            // B pixel +            { +                out->r = applyFilter(in, x, y, w, h, R_BGB); +                out->g = applyFilter(in, x, y, w, h, G_BGB); +                out->b = in[x + offset]; +            } +        } +    } +} + +static void swapRedAndBlue(int N, Color3uint8* out) { +    for (int i = N - 1; i >= 0; --i) { +        uint8 tmp = out[i].r; +        out[i].r = out[i].b; +        out[i].b = tmp; +    } +} + +void GImage::BAYER_G8R8_B8G8_to_R8G8B8_MHC(int w, int h, const uint8* in, uint8* _out) { +    // Run the equivalent function for red +    BAYER_G8B8_R8G8_to_R8G8B8_MHC(w, h, in, _out); + +    // Now swap red and blue +    swapRedAndBlue(w * h, (Color3uint8*)_out); +} + + +void GImage::BAYER_B8G8_G8R8_to_R8G8B8_MHC(int w, int h, const uint8* in, uint8* _out) { +    // Run the equivalent function for red +    BAYER_R8G8_G8B8_to_R8G8B8_MHC(w, h, in, _out); + +    // Now swap red and blue +    swapRedAndBlue(w * h, (Color3uint8*)_out); +} + + +void GImage::BAYER_G8B8_R8G8_to_R8G8B8_MHC(int w, int h, const uint8* in, uint8* _out) { + +    debugAssert(in != _out); + +    Color3uint8* out = (Color3uint8*)_out; + +    for (int y = 0; y < h; ++y) { + +        // Row beginning in the input array. +        int offset = y * w; + +        // GB row +        for (int x = 0; x < w; ++x, ++out) { +            // G pixel +            { +                out->r = applyFilter(in, x, y, w, h, R_BGG); +                out->g = in[x + offset]; +                out->b = applyFilter(in, x, y, w, h, B_BGG); +            } +            ++x; ++out; + +            // B pixel +            { +                out->r = applyFilter(in, x, y, w, h, R_BGB); +                out->g = applyFilter(in, x, y, w, h, G_BGB); +                out->b = in[x + offset]; +            } +        } + +        ++y; +        offset += w; + +        // RG row +        for (int x = 0; x < w; ++x, ++out) { +            // R pixel +            { +                out->r = in[x + offset]; +                out->g = applyFilter(in, x, y, w, h, G_GRR); +                out->b = applyFilter(in, x, y, w, h, B_GRR); +            } +            ++x; ++out; + +            // G pixel +            { +                out->r = applyFilter(in, x, y, w, h, R_GRG); +                out->g = in[x + offset]; +                out->b = applyFilter(in, x, y, w, h, B_GRG); +            } +        } +    } + +} + +#undef B_BGG +#undef B_GRG +#undef B_GRR + +}  | 
