Coverage Report

Created: 2025-01-23 06:28

/src/dng_sdk/source/dng_hue_sat_map.cpp
Line
Count
Source (jump to first uncovered line)
1
/*****************************************************************************/
2
// Copyright 2007 Adobe Systems Incorporated
3
// All Rights Reserved.
4
//
5
// NOTICE:  Adobe permits you to use, modify, and distribute this file in
6
// accordance with the terms of the Adobe license agreement accompanying it.
7
/*****************************************************************************/
8
9
/* $Id: //mondo/dng_sdk_1_4/dng_sdk/source/dng_hue_sat_map.cpp#1 $ */ 
10
/* $DateTime: 2012/05/30 13:28:51 $ */
11
/* $Change: 832332 $ */
12
/* $Author: tknoll $ */
13
14
/*****************************************************************************/
15
16
#include "dng_hue_sat_map.h"
17
18
#include "dng_assertions.h"
19
#include "dng_auto_ptr.h"
20
#include "dng_bottlenecks.h"
21
#include "dng_exceptions.h"
22
#include "dng_host.h"
23
24
/*****************************************************************************/
25
26
dng_hue_sat_map::dng_hue_sat_map ()
27
28
2.52k
  : fHueDivisions (0)
29
2.52k
  , fSatDivisions (0)
30
2.52k
  , fValDivisions (0)
31
2.52k
  , fHueStep      (0)
32
2.52k
  , fValStep    (0)
33
2.52k
  , fDeltas       ()
34
  
35
2.52k
  {
36
  
37
2.52k
  }
38
39
/*****************************************************************************/
40
41
dng_hue_sat_map::dng_hue_sat_map (const dng_hue_sat_map &src)
42
43
0
  : fHueDivisions (0)
44
0
  , fSatDivisions (0)
45
0
  , fValDivisions (0)
46
0
  , fHueStep      (0)
47
0
  , fValStep    (0)
48
0
  , fDeltas       ()
49
50
0
  {
51
  
52
0
  *this = src;
53
  
54
0
  }
55
56
/*****************************************************************************/
57
58
dng_hue_sat_map &dng_hue_sat_map::operator= (const dng_hue_sat_map &rhs)
59
0
  { 
60
61
0
  if (this != &rhs)
62
0
    {
63
64
0
    if (!rhs.IsValid ())
65
0
      {
66
      
67
0
      SetInvalid ();
68
      
69
0
      }
70
      
71
0
    else
72
0
      {
73
74
0
      fHueDivisions = rhs.fHueDivisions;
75
0
      fSatDivisions = rhs.fSatDivisions;
76
0
      fValDivisions = rhs.fValDivisions;
77
78
0
      fHueStep = rhs.fHueStep;
79
0
      fValStep = rhs.fValStep;
80
81
0
      fDeltas = rhs.fDeltas;
82
        
83
0
      }
84
85
0
    }
86
87
0
  return *this;
88
89
0
  }
90
91
/*****************************************************************************/
92
93
dng_hue_sat_map::~dng_hue_sat_map ()
94
2.52k
  {
95
  
96
2.52k
  }
97
98
/*****************************************************************************/
99
100
void dng_hue_sat_map::SetDivisions (uint32 hueDivisions,
101
                  uint32 satDivisions,
102
                  uint32 valDivisions)
103
251
  {
104
105
251
  DNG_ASSERT (hueDivisions >= 1, "Must have at least 1 hue division.");
106
251
  DNG_ASSERT (satDivisions >= 2, "Must have at least 2 sat divisions.");
107
  
108
251
  if (valDivisions == 0)
109
72
    valDivisions = 1;
110
111
251
  if (hueDivisions == fHueDivisions &&
112
251
    satDivisions == fSatDivisions &&
113
251
    valDivisions == fValDivisions)
114
0
    {
115
0
    return;
116
0
    }
117
118
251
  fHueDivisions = hueDivisions;
119
251
  fSatDivisions = satDivisions;
120
251
  fValDivisions = valDivisions;
121
  
122
251
  fHueStep = satDivisions;
123
251
  fValStep = SafeUint32Mult(hueDivisions, fHueStep);
124
125
251
  uint32 size = SafeUint32Mult(DeltasCount (), (uint32) sizeof (HSBModify));
126
  
127
251
  fDeltas.Allocate (size);
128
  
129
251
  DoZeroBytes (fDeltas.Buffer (), size);
130
131
251
  }
132
133
/*****************************************************************************/
134
135
void dng_hue_sat_map::GetDelta (uint32 hueDiv,
136
                uint32 satDiv,
137
                uint32 valDiv,
138
                HSBModify &modify) const
139
87.3M
  {
140
141
87.3M
  if (hueDiv >= fHueDivisions ||
142
87.3M
    satDiv >= fSatDivisions ||
143
87.3M
    valDiv >= fValDivisions ||
144
87.3M
    fDeltas.Buffer () == NULL)
145
0
    {
146
    
147
0
    DNG_REPORT ("Bad parameters to dng_hue_sat_map::GetDelta");
148
    
149
0
    ThrowProgramError ();
150
    
151
0
    }
152
153
87.3M
  int32 offset = valDiv * fValStep +
154
87.3M
           hueDiv * fHueStep +
155
87.3M
           satDiv;
156
157
87.3M
  const HSBModify *deltas = GetConstDeltas ();
158
159
87.3M
  modify.fHueShift = deltas [offset].fHueShift;
160
87.3M
  modify.fSatScale = deltas [offset].fSatScale;
161
87.3M
  modify.fValScale = deltas [offset].fValScale;
162
163
87.3M
  }
164
165
/*****************************************************************************/
166
167
void dng_hue_sat_map::SetDeltaKnownWriteable (uint32 hueDiv,
168
                        uint32 satDiv,
169
                        uint32 valDiv,
170
                        const HSBModify &modify)
171
872k
  {
172
173
872k
  if (hueDiv >= fHueDivisions ||
174
872k
    satDiv >= fSatDivisions ||
175
872k
    valDiv >= fValDivisions ||
176
872k
    fDeltas.Buffer () == NULL)
177
0
    {
178
    
179
0
    DNG_REPORT ("Bad parameters to dng_hue_sat_map::SetDelta");
180
    
181
0
    ThrowProgramError ();
182
    
183
0
    }
184
    
185
  // Set this entry.
186
    
187
872k
  int32 offset = valDiv * fValStep +
188
872k
           hueDiv * fHueStep +
189
872k
           satDiv;
190
191
872k
  SafeGetDeltas () [offset] = modify;
192
  
193
  // The zero saturation entry is required to have a value scale
194
  // of 1.0f.
195
  
196
872k
  if (satDiv == 0)
197
78.2k
    {
198
    
199
78.2k
    if (modify.fValScale != 1.0f)
200
1.74k
      {
201
      
202
      #if qDNGValidate
203
    
204
      ReportWarning ("Value scale for zero saturation entries must be 1.0");
205
             
206
      #endif
207
      
208
1.74k
      SafeGetDeltas () [offset] . fValScale = 1.0f;
209
    
210
1.74k
      }
211
    
212
78.2k
    }
213
    
214
  // If we are settings the first saturation entry and we have not
215
  // set the zero saturation entry yet, fill in the zero saturation entry
216
  // by extrapolating first saturation entry.
217
  
218
872k
  if (satDiv == 1)
219
76.8k
    {
220
    
221
76.8k
    HSBModify zeroSatModify;
222
    
223
76.8k
    GetDelta (hueDiv, 0, valDiv, zeroSatModify);
224
    
225
76.8k
    if (zeroSatModify.fValScale != 1.0f)
226
76.2k
      {
227
      
228
76.2k
      zeroSatModify.fHueShift = modify.fHueShift;
229
76.2k
      zeroSatModify.fSatScale = modify.fSatScale;
230
76.2k
      zeroSatModify.fValScale = 1.0f;
231
      
232
76.2k
      SetDelta (hueDiv, 0, valDiv, zeroSatModify);
233
      
234
76.2k
      }
235
    
236
76.8k
    }
237
238
872k
  }
239
240
/*****************************************************************************/
241
242
bool dng_hue_sat_map::operator== (const dng_hue_sat_map &rhs) const
243
0
  {
244
  
245
0
  if (fHueDivisions != rhs.fHueDivisions ||
246
0
    fSatDivisions != rhs.fSatDivisions ||
247
0
    fValDivisions != rhs.fValDivisions)
248
0
    return false;
249
250
0
  if (!IsValid ())
251
0
    return true;
252
253
0
  return memcmp (GetConstDeltas (),
254
0
           rhs.GetConstDeltas (),
255
0
           DeltasCount () * sizeof (HSBModify)) == 0;
256
257
0
  }
258
259
/*****************************************************************************/
260
261
dng_hue_sat_map * dng_hue_sat_map::Interpolate (const dng_hue_sat_map &map1,
262
                          const dng_hue_sat_map &map2,
263
                          real64 weight1)
264
0
  {
265
  
266
0
  if (weight1 >= 1.0)
267
0
    {
268
    
269
0
    if (!map1.IsValid ())
270
0
      {
271
      
272
0
      DNG_REPORT ("map1 is not valid");
273
      
274
0
      ThrowProgramError ();
275
      
276
0
      }
277
      
278
0
    return new dng_hue_sat_map (map1);
279
    
280
0
    }
281
    
282
0
  if (weight1 <= 0.0)
283
0
    {
284
    
285
0
    if (!map2.IsValid ())
286
0
      {     
287
0
      DNG_REPORT ("map2 is not valid");
288
      
289
0
      ThrowProgramError ();
290
      
291
0
      }
292
      
293
0
    return new dng_hue_sat_map (map2);
294
    
295
0
    }
296
    
297
  // Both maps must be valid if we are using both.
298
  
299
0
  if (!map1.IsValid () || !map2.IsValid ())
300
0
    {
301
      
302
0
    DNG_REPORT ("map1 or map2 is not valid");
303
    
304
0
    ThrowProgramError ();
305
    
306
0
    }
307
    
308
  // Must have the same dimensions.
309
  
310
0
  if (map1.fHueDivisions != map2.fHueDivisions ||
311
0
    map1.fSatDivisions != map2.fSatDivisions ||
312
0
    map1.fValDivisions != map2.fValDivisions)
313
0
    {
314
    
315
0
    DNG_REPORT ("map1 and map2 have different sizes");
316
    
317
0
    ThrowProgramError ();
318
    
319
0
    }
320
    
321
  // Make table to hold interpolated results.
322
  
323
0
  AutoPtr<dng_hue_sat_map> result (new dng_hue_sat_map);
324
  
325
0
  result->SetDivisions (map1.fHueDivisions,
326
0
              map1.fSatDivisions,
327
0
              map1.fValDivisions);
328
              
329
  // Interpolate between the tables.
330
  
331
0
  real32 w1 = (real32) weight1;
332
0
  real32 w2 = 1.0f - w1;
333
  
334
0
  const HSBModify *data1 = map1.GetConstDeltas ();
335
0
  const HSBModify *data2 = map2.GetConstDeltas ();
336
  
337
0
  HSBModify *data3 = result->SafeGetDeltas ();
338
  
339
0
  uint32 count = map1.DeltasCount ();
340
  
341
0
  for (uint32 index = 0; index < count; index++)
342
0
    {
343
    
344
0
    data3->fHueShift = w1 * data1->fHueShift +
345
0
               w2 * data2->fHueShift;
346
               
347
0
    data3->fSatScale = w1 * data1->fSatScale +
348
0
               w2 * data2->fSatScale;
349
               
350
0
    data3->fValScale = w1 * data1->fValScale +
351
0
               w2 * data2->fValScale;
352
               
353
0
    data1++;
354
0
    data2++;
355
0
    data3++;
356
    
357
0
    }
358
    
359
  // Return interpolated tables.
360
  
361
0
  return result.Release ();
362
    
363
0
  }
364
365
/*****************************************************************************/