~ubuntu-branches/ubuntu/wily/oolite/wily-proposed

« back to all changes in this revision

Viewing changes to tools/planettool/FloatPixMap/FPMGamma.c

  • Committer: Package Import Robot
  • Author(s): Nicolas Boulenguez
  • Date: 2011-12-22 00:22:39 UTC
  • mfrom: (1.2.2)
  • Revision ID: package-import@ubuntu.com-20111222002239-pr3upeupp4jw1psp
Tags: 1.76-1
* New upstream.
* watch: scan upstream stable releases instead of dev snapshots.
* control: use default gobjc instead of explicit 4.6.
* rules: use dpkg-dev build flags.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 *  FPMGamma.c
 
3
 *  planettool
 
4
 *
 
5
 *  Created by Jens Ayton on 2009-10-01.
 
6
 *  Copyright 2009 Jens Ayton. All rights reserved.
 
7
 *
 
8
 */
 
9
 
 
10
#include "FPMGamma.h"
 
11
#include "FPMImageOperations.h"
 
12
 
 
13
 
 
14
const FPMGammaFactor kFPMGammaLinear                    = 1.0f;
 
15
const FPMGammaFactor kFPMGammaSRGB                              = 2.2f;
 
16
const FPMGammaFactor kFPMGammaTraditionalMac    = 1.8f;
 
17
 
 
18
 
 
19
#ifndef FPM_GAMMA_USE_LUT
 
20
#define FPM_GAMMA_USE_LUT 0
 
21
#endif
 
22
 
 
23
 
 
24
void ApplyGammaDirect(FloatPixMapRef pm, FPMColor *pixel, FPMPoint coords, void *info)
 
25
{
 
26
        FPMGammaFactor gamma = *(FPMGammaFactor *)info;
 
27
        pixel->r = powf(pixel->r, gamma);
 
28
        pixel->g = powf(pixel->g, gamma);
 
29
        pixel->b = powf(pixel->b, gamma);
 
30
}
 
31
 
 
32
 
 
33
#if FPM_GAMMA_USE_LUT
 
34
 
 
35
typedef struct ApplyGammaLUTInfo
 
36
{
 
37
        float                   scale;
 
38
        unsigned                entries;
 
39
        float                   *lut;
 
40
} ApplyGammaLUTInfo;
 
41
 
 
42
 
 
43
FPM_INLINE float ApplyGammaOne(float value, ApplyGammaLUTInfo *info)
 
44
{
 
45
        if (value > 0.0f)
 
46
        {
 
47
                unsigned index = value * info->scale;
 
48
                if (index < info->entries)  value = info->lut[index];
 
49
        }
 
50
        return value;
 
51
}
 
52
 
 
53
 
 
54
void ApplyGammaLUT(FloatPixMapRef pm, FPMColor *pixel, FPMPoint coords, void *info)
 
55
{
 
56
        pixel->r = ApplyGammaOne(pixel->r, info);
 
57
        pixel->g = ApplyGammaOne(pixel->g, info);
 
58
        pixel->b = ApplyGammaOne(pixel->b, info);
 
59
}
 
60
 
 
61
#endif
 
62
 
 
63
 
 
64
void FPMApplyGamma(FloatPixMapRef pm, FPMGammaFactor currentGamma, FPMGammaFactor desiredGamma, unsigned steps)
 
65
{
 
66
        if (pm != NULL && currentGamma != desiredGamma && steps > 1)
 
67
        {
 
68
                FPMGammaFactor resultingGamma = currentGamma / desiredGamma;
 
69
                
 
70
#if FPM_GAMMA_USE_LUT
 
71
                if (steps >= FPMGetArea(pm) * 5)        // 5 is a fudge factor; 3 would strictly minimize number of powf() calls.
 
72
                {
 
73
                        // No point in building a LUT if picture is not much bigger than LUT.
 
74
                        FPMForEachPixelF(pm, ApplyGammaDirect, &resultingGamma);
 
75
                        return;
 
76
                }
 
77
                
 
78
                static float *lookupTable = NULL;
 
79
                static unsigned lastTableSize = 0;
 
80
                static float lastGamma;
 
81
                
 
82
                if (lastTableSize != steps || resultingGamma != lastGamma)
 
83
                {
 
84
                        free(lookupTable);
 
85
                        lookupTable = malloc(steps * sizeof (float));
 
86
                        if (lookupTable == NULL)
 
87
                        {
 
88
                                // Fallback: apply gamma the slow way.
 
89
                                FPMForEachPixelF(pm, ApplyGammaDirect, &resultingGamma);
 
90
                                return;
 
91
                        }
 
92
                        
 
93
                        unsigned i;
 
94
                        for (i = 0; i < steps; i++)
 
95
                        {
 
96
                                lookupTable[i] = powf((float)i / (float)steps, resultingGamma);
 
97
                        }
 
98
                }
 
99
                
 
100
                ApplyGammaLUTInfo info =
 
101
                {
 
102
                        steps,
 
103
                        steps,
 
104
                        lookupTable
 
105
                };
 
106
                
 
107
                FPMForEachPixelF(pm, ApplyGammaLUT, &info);
 
108
#else
 
109
                FPMForEachPixelF(pm, ApplyGammaDirect, &resultingGamma);
 
110
#endif
 
111
        }
 
112
}