Coverage Report

Created: 2025-06-09 07:43

/src/gdal/frmts/pcraster/pcrasterutil.cpp
Line
Count
Source (jump to first uncovered line)
1
/******************************************************************************
2
 *
3
 * Project:  PCRaster Integration
4
 * Purpose:  PCRaster driver support functions.
5
 * Author:   Kor de Jong, Oliver Schmitz
6
 *
7
 ******************************************************************************
8
 * Copyright (c) PCRaster owners
9
 *
10
 * SPDX-License-Identifier: MIT
11
 ****************************************************************************/
12
13
#include <cfloat>
14
15
#include <algorithm>
16
#include <limits>
17
18
#include "pcrasterutil.h"
19
#include "pcrtypes.h"
20
21
//! Converts PCRaster data type to GDAL data type.
22
/*!
23
  \param     cellRepresentation Cell representation.
24
  \return    GDAL data type, GDT_Uknown if conversion is not possible.
25
*/
26
GDALDataType cellRepresentation2GDALType(CSF_CR cellRepresentation)
27
0
{
28
0
    GDALDataType type = GDT_Unknown;
29
30
0
    switch (cellRepresentation)
31
0
    {
32
        // CSF version 2.
33
        // ----------------------------------------------------------
34
0
        case CR_UINT1:
35
0
        {
36
0
            type = GDT_Byte;
37
0
            break;
38
0
        }
39
0
        case CR_INT4:
40
0
        {
41
0
            type = GDT_Int32;
42
0
            break;
43
0
        }
44
0
        case CR_REAL4:
45
0
        {
46
0
            type = GDT_Float32;
47
0
            break;
48
0
        }
49
0
        case CR_REAL8:
50
0
        {
51
0
            type = GDT_Float64;
52
0
            break;
53
0
        }
54
        // CSF version 1.
55
        // ----------------------------------------------------------
56
0
        case CR_INT1:
57
0
        {
58
0
            type = GDT_Byte;
59
0
            break;
60
0
        }
61
0
        case CR_INT2:
62
0
        {
63
0
            type = GDT_Int16;
64
0
            break;
65
0
        }
66
0
        case CR_UINT2:
67
0
        {
68
0
            type = GDT_UInt16;
69
0
            break;
70
0
        }
71
0
        case CR_UINT4:
72
0
        {
73
0
            type = GDT_UInt32;
74
0
            break;
75
0
        }
76
0
        default:
77
0
        {
78
0
            break;
79
0
        }
80
0
    }
81
82
0
    return type;
83
0
}
84
85
CSF_VS string2ValueScale(std::string const &string)
86
0
{
87
0
    CSF_VS valueScale = VS_UNDEFINED;
88
89
    // CSF version 2.
90
    // ------------------------------------------------------------
91
0
    if (string == "VS_BOOLEAN")
92
0
    {
93
0
        valueScale = VS_BOOLEAN;
94
0
    }
95
0
    else if (string == "VS_NOMINAL")
96
0
    {
97
0
        valueScale = VS_NOMINAL;
98
0
    }
99
0
    else if (string == "VS_ORDINAL")
100
0
    {
101
0
        valueScale = VS_ORDINAL;
102
0
    }
103
0
    else if (string == "VS_SCALAR")
104
0
    {
105
0
        valueScale = VS_SCALAR;
106
0
    }
107
0
    else if (string == "VS_DIRECTION")
108
0
    {
109
0
        valueScale = VS_DIRECTION;
110
0
    }
111
0
    else if (string == "VS_LDD")
112
0
    {
113
0
        valueScale = VS_LDD;
114
0
    }
115
    // CSF version1.
116
    // -------------------------------------------------------------
117
0
    else if (string == "VS_CLASSIFIED")
118
0
    {
119
0
        valueScale = VS_CLASSIFIED;
120
0
    }
121
0
    else if (string == "VS_CONTINUOUS")
122
0
    {
123
0
        valueScale = VS_CONTINUOUS;
124
0
    }
125
0
    else if (string == "VS_NOTDETERMINED")
126
0
    {
127
0
        valueScale = VS_NOTDETERMINED;
128
0
    }
129
130
0
    return valueScale;
131
0
}
132
133
std::string valueScale2String(CSF_VS valueScale)
134
0
{
135
0
    std::string result = "VS_UNDEFINED";
136
137
0
    switch (valueScale)
138
0
    {
139
        // CSF version 2.
140
        // ----------------------------------------------------------
141
0
        case VS_BOOLEAN:
142
0
        {
143
0
            result = "VS_BOOLEAN";
144
0
            break;
145
0
        }
146
0
        case VS_NOMINAL:
147
0
        {
148
0
            result = "VS_NOMINAL";
149
0
            break;
150
0
        }
151
0
        case VS_ORDINAL:
152
0
        {
153
0
            result = "VS_ORDINAL";
154
0
            break;
155
0
        }
156
0
        case VS_SCALAR:
157
0
        {
158
0
            result = "VS_SCALAR";
159
0
            break;
160
0
        }
161
0
        case VS_DIRECTION:
162
0
        {
163
0
            result = "VS_DIRECTION";
164
0
            break;
165
0
        }
166
0
        case VS_LDD:
167
0
        {
168
0
            result = "VS_LDD";
169
0
            break;
170
0
        }
171
        // CSF version 1.
172
        // ----------------------------------------------------------
173
0
        case VS_CLASSIFIED:
174
0
        {
175
0
            result = "VS_CLASSIFIED";
176
0
            break;
177
0
        }
178
0
        case VS_CONTINUOUS:
179
0
        {
180
0
            result = "VS_CONTINUOUS";
181
0
            break;
182
0
        }
183
0
        case VS_NOTDETERMINED:
184
0
        {
185
0
            result = "VS_NOTDETERMINED";
186
0
            break;
187
0
        }
188
0
        default:
189
0
        {
190
0
            break;
191
0
        }
192
0
    }
193
194
0
    return result;
195
0
}
196
197
std::string cellRepresentation2String(CSF_CR cellRepresentation)
198
0
{
199
0
    std::string result = "CR_UNDEFINED";
200
201
0
    switch (cellRepresentation)
202
0
    {
203
204
        // CSF version 2.
205
        // ----------------------------------------------------------
206
0
        case CR_UINT1:
207
0
        {
208
0
            result = "CR_UINT1";
209
0
            break;
210
0
        }
211
0
        case CR_INT4:
212
0
        {
213
0
            result = "CR_INT4";
214
0
            break;
215
0
        }
216
0
        case CR_REAL4:
217
0
        {
218
0
            result = "CR_REAL4";
219
0
            break;
220
0
        }
221
0
        case CR_REAL8:
222
0
        {
223
0
            result = "CR_REAL8";
224
0
            break;
225
0
        }
226
        // CSF version 1.
227
        // ----------------------------------------------------------
228
0
        case CR_INT1:
229
0
        {
230
0
            result = "CR_INT1";
231
0
            break;
232
0
        }
233
0
        case CR_INT2:
234
0
        {
235
0
            result = "CR_INT2";
236
0
            break;
237
0
        }
238
0
        case CR_UINT2:
239
0
        {
240
0
            result = "CR_UINT2";
241
0
            break;
242
0
        }
243
0
        case CR_UINT4:
244
0
        {
245
0
            result = "CR_UINT4";
246
0
            break;
247
0
        }
248
0
        default:
249
0
        {
250
0
            break;
251
0
        }
252
0
    }
253
254
0
    return result;
255
0
}
256
257
//! Converts GDAL data type to PCRaster value scale.
258
/*!
259
  \param     type GDAL data type.
260
  \return    Value scale.
261
  \warning   \a type must be one of the standard numerical types and not
262
             complex.
263
264
  GDAL byte is regarded as PCRaster boolean, integral as nominal and float
265
  as scalar. This function will never return VS_LDD, VS_ORDINAL or
266
  VS_DIRECTION.
267
*/
268
CSF_VS GDALType2ValueScale(GDALDataType type)
269
0
{
270
0
    CSF_VS valueScale = VS_UNDEFINED;
271
272
0
    switch (type)
273
0
    {
274
0
        case GDT_Byte:
275
0
        {
276
            // A foreign dataset is unlikely to support our LDD's.
277
0
            valueScale = VS_BOOLEAN;
278
0
            break;
279
0
        }
280
0
        case GDT_UInt16:
281
0
        case GDT_UInt32:
282
0
        case GDT_Int16:
283
0
        case GDT_Int32:
284
0
        {
285
0
            valueScale = VS_NOMINAL;
286
0
            break;
287
0
        }
288
0
        case GDT_Float32:
289
0
        {
290
            // A foreign dataset is unlikely to support our directional.
291
0
            valueScale = VS_SCALAR;
292
0
            break;
293
0
        }
294
0
        case GDT_Float64:
295
0
        {
296
            // A foreign dataset is unlikely to support our directional.
297
0
            valueScale = VS_SCALAR;
298
0
            break;
299
0
        }
300
0
        default:
301
0
        {
302
0
            CPLAssert(false);
303
0
            break;
304
0
        }
305
0
    }
306
307
0
    return valueScale;
308
0
}
309
310
//! Converts a GDAL type to a PCRaster cell representation.
311
/*!
312
  \param     type GDAL type.
313
  \param     exact Whether an exact match or a CSF2.0 supported cell
314
                   representation should be returned.
315
  \return    Cell representation.
316
  \warning   \a type must be one of the standard numerical types and not
317
             complex.
318
319
  If exact is false, conversion to CSF2.0 types will take place. This is
320
  useful for in file cell representations. If exact is true, and exact match
321
  is made. This is useful for in app cell representations.
322
323
  If exact is false, this function always returns one of CR_UINT1, CR_INT4
324
  or CR_REAL4.
325
*/
326
CSF_CR GDALType2CellRepresentation(GDALDataType type, bool exact)
327
0
{
328
0
    CSF_CR cellRepresentation = CR_UNDEFINED;
329
330
0
    switch (type)
331
0
    {
332
0
        case GDT_Byte:
333
0
        {
334
0
            cellRepresentation = CR_UINT1;
335
0
            break;
336
0
        }
337
0
        case GDT_UInt16:
338
0
        {
339
0
            cellRepresentation = exact ? CR_UINT2 : CR_UINT1;
340
0
            break;
341
0
        }
342
0
        case GDT_UInt32:
343
0
        {
344
0
            cellRepresentation = exact ? CR_UINT4 : CR_UINT1;
345
0
            break;
346
0
        }
347
0
        case GDT_Int16:
348
0
        {
349
0
            cellRepresentation = exact ? CR_INT2 : CR_INT4;
350
0
            break;
351
0
        }
352
0
        case GDT_Int32:
353
0
        {
354
0
            cellRepresentation = CR_INT4;
355
0
            break;
356
0
        }
357
0
        case GDT_Float32:
358
0
        {
359
0
            cellRepresentation = CR_REAL4;
360
0
            break;
361
0
        }
362
0
        case GDT_Float64:
363
0
        {
364
0
            cellRepresentation = exact ? CR_REAL8 : CR_REAL4;
365
0
            break;
366
0
        }
367
0
        default:
368
0
        {
369
0
            break;
370
0
        }
371
0
    }
372
373
0
    return cellRepresentation;
374
0
}
375
376
//! Determines a missing value to use for data of \a cellRepresentation.
377
/*!
378
  \param     cellRepresentation Cell representation of the data.
379
  \return    Missing value.
380
*/
381
double missingValue(CSF_CR cellRepresentation)
382
0
{
383
    // It turns out that the missing values set here should be equal to the ones
384
    // used in gdal's code to do data type conversion. Otherwise missing values
385
    // in the source raster will be lost in the destination raster. It seems
386
    // that when assigning new missing values gdal uses its own nodata values
387
    // instead of the value set in the dataset.
388
389
0
    double missingValue = 0.0;
390
391
0
    switch (cellRepresentation)
392
0
    {
393
        // CSF version 2.
394
        // ----------------------------------------------------------
395
0
        case CR_UINT1:
396
0
        {
397
            // missingValue = static_cast<double>(MV_UINT1);
398
0
            missingValue = UINT1(255);
399
0
            break;
400
0
        }
401
0
        case CR_INT4:
402
0
        {
403
            // missingValue = static_cast<double>(MV_INT4);
404
0
            missingValue = INT4(-2147483647);
405
0
            break;
406
0
        }
407
0
        case CR_REAL4:
408
0
        {
409
            // using <limits> breaks on gcc 2.95
410
            // CPLAssert(std::numeric_limits<REAL4>::is_iec559);
411
            // missingValue = -std::numeric_limits<REAL4>::max();
412
0
            missingValue = std::numeric_limits<float>::lowest();
413
0
            break;
414
0
        }
415
        // CSF version 1.
416
        // ----------------------------------------------------------
417
0
        case CR_INT1:
418
0
        {
419
0
            missingValue = static_cast<double>(MV_INT1);
420
0
            break;
421
0
        }
422
0
        case CR_INT2:
423
0
        {
424
0
            missingValue = static_cast<double>(MV_INT2);
425
0
            break;
426
0
        }
427
0
        case CR_UINT2:
428
0
        {
429
0
            missingValue = static_cast<double>(MV_UINT2);
430
0
            break;
431
0
        }
432
0
        case CR_UINT4:
433
0
        {
434
0
            missingValue = static_cast<double>(MV_UINT4);
435
0
            break;
436
0
        }
437
0
        default:
438
0
        {
439
0
            CPLError(CE_Failure, CPLE_NotSupported,
440
0
                     "Unexpected value for cellRepresentation = %d",
441
0
                     cellRepresentation);
442
0
            break;
443
0
        }
444
0
    }
445
446
0
    return missingValue;
447
0
}
448
449
//! Opens the raster in \a filename using mode \a mode.
450
/*!
451
  \param     filename Filename of raster to open.
452
  \return    Pointer to CSF MAP structure.
453
*/
454
MAP *mapOpen(std::string const &filename, MOPEN_PERM mode)
455
1
{
456
1
    MAP *map = Mopen(filename.c_str(), mode);
457
458
1
    return map;
459
1
}
460
461
void alterFromStdMV(void *buffer, size_t size, CSF_CR cellRepresentation,
462
                    double missingValue)
463
0
{
464
0
    switch (cellRepresentation)
465
0
    {
466
        // CSF version 2.
467
        // ----------------------------------------------------------
468
0
        case (CR_UINT1):
469
0
        {
470
0
            std::for_each(
471
0
                static_cast<UINT1 *>(buffer),
472
0
                static_cast<UINT1 *>(buffer) + size,
473
0
                pcr::AlterFromStdMV<UINT1>(static_cast<UINT1>(missingValue)));
474
0
            break;
475
0
        }
476
0
        case (CR_INT4):
477
0
        {
478
0
            std::for_each(
479
0
                static_cast<INT4 *>(buffer), static_cast<INT4 *>(buffer) + size,
480
0
                pcr::AlterFromStdMV<INT4>(static_cast<INT4>(missingValue)));
481
0
            break;
482
0
        }
483
0
        case (CR_REAL4):
484
0
        {
485
0
            std::for_each(
486
0
                static_cast<REAL4 *>(buffer),
487
0
                static_cast<REAL4 *>(buffer) + size,
488
0
                pcr::AlterFromStdMV<REAL4>(static_cast<REAL4>(missingValue)));
489
0
            break;
490
0
        }
491
0
        case (CR_REAL8):
492
0
        {
493
0
            std::for_each(
494
0
                static_cast<REAL8 *>(buffer),
495
0
                static_cast<REAL8 *>(buffer) + size,
496
0
                pcr::AlterFromStdMV<REAL8>(static_cast<REAL8>(missingValue)));
497
0
            break;
498
0
        }
499
        // CSF version 1.
500
        // ----------------------------------------------------------
501
0
        case CR_INT1:
502
0
        {
503
0
            std::for_each(
504
0
                static_cast<INT1 *>(buffer), static_cast<INT1 *>(buffer) + size,
505
0
                pcr::AlterFromStdMV<INT1>(static_cast<INT1>(missingValue)));
506
0
            break;
507
0
        }
508
0
        case CR_INT2:
509
0
        {
510
0
            std::for_each(
511
0
                static_cast<INT2 *>(buffer), static_cast<INT2 *>(buffer) + size,
512
0
                pcr::AlterFromStdMV<INT2>(static_cast<INT2>(missingValue)));
513
0
            break;
514
0
        }
515
0
        case CR_UINT2:
516
0
        {
517
0
            std::for_each(
518
0
                static_cast<UINT2 *>(buffer),
519
0
                static_cast<UINT2 *>(buffer) + size,
520
0
                pcr::AlterFromStdMV<UINT2>(static_cast<UINT2>(missingValue)));
521
0
            break;
522
0
        }
523
0
        case CR_UINT4:
524
0
        {
525
0
            std::for_each(
526
0
                static_cast<UINT4 *>(buffer),
527
0
                static_cast<UINT4 *>(buffer) + size,
528
0
                pcr::AlterFromStdMV<UINT4>(static_cast<UINT4>(missingValue)));
529
0
            break;
530
0
        }
531
0
        default:
532
0
        {
533
0
            CPLAssert(false);
534
0
            break;
535
0
        }
536
0
    }
537
0
}
538
539
void alterToStdMV(void *buffer, size_t size, CSF_CR cellRepresentation,
540
                  double missingValue)
541
0
{
542
0
    switch (cellRepresentation)
543
0
    {
544
        // CSF version 2.
545
        // ----------------------------------------------------------
546
0
        case (CR_UINT1):
547
0
        {
548
0
            std::for_each(
549
0
                static_cast<UINT1 *>(buffer),
550
0
                static_cast<UINT1 *>(buffer) + size,
551
0
                pcr::AlterToStdMV<UINT1>(static_cast<UINT1>(missingValue)));
552
0
            break;
553
0
        }
554
0
        case (CR_INT4):
555
0
        {
556
0
            std::for_each(
557
0
                static_cast<INT4 *>(buffer), static_cast<INT4 *>(buffer) + size,
558
0
                pcr::AlterToStdMV<INT4>(static_cast<INT4>(missingValue)));
559
0
            break;
560
0
        }
561
0
        case (CR_REAL4):
562
0
        {
563
0
            std::for_each(
564
0
                static_cast<REAL4 *>(buffer),
565
0
                static_cast<REAL4 *>(buffer) + size,
566
0
                pcr::AlterToStdMV<REAL4>(static_cast<REAL4>(missingValue)));
567
0
            break;
568
0
        }
569
0
        case (CR_REAL8):
570
0
        {
571
0
            std::for_each(
572
0
                static_cast<REAL8 *>(buffer),
573
0
                static_cast<REAL8 *>(buffer) + size,
574
0
                pcr::AlterToStdMV<REAL8>(static_cast<REAL8>(missingValue)));
575
0
            break;
576
0
        }
577
        // CSF version 1.
578
        // ----------------------------------------------------------
579
0
        case CR_INT1:
580
0
        {
581
0
            std::for_each(
582
0
                static_cast<INT1 *>(buffer), static_cast<INT1 *>(buffer) + size,
583
0
                pcr::AlterToStdMV<INT1>(static_cast<INT1>(missingValue)));
584
0
            break;
585
0
        }
586
0
        case CR_INT2:
587
0
        {
588
0
            std::for_each(
589
0
                static_cast<INT2 *>(buffer), static_cast<INT2 *>(buffer) + size,
590
0
                pcr::AlterToStdMV<INT2>(static_cast<INT2>(missingValue)));
591
0
            break;
592
0
        }
593
0
        case CR_UINT2:
594
0
        {
595
0
            std::for_each(
596
0
                static_cast<UINT2 *>(buffer),
597
0
                static_cast<UINT2 *>(buffer) + size,
598
0
                pcr::AlterToStdMV<UINT2>(static_cast<UINT2>(missingValue)));
599
0
            break;
600
0
        }
601
0
        case CR_UINT4:
602
0
        {
603
0
            std::for_each(
604
0
                static_cast<UINT4 *>(buffer),
605
0
                static_cast<UINT4 *>(buffer) + size,
606
0
                pcr::AlterToStdMV<UINT4>(static_cast<UINT4>(missingValue)));
607
0
            break;
608
0
        }
609
0
        default:
610
0
        {
611
0
            CPLAssert(false);
612
0
            break;
613
0
        }
614
0
    }
615
0
}
616
617
CSF_VS fitValueScale(CSF_VS valueScale, CSF_CR cellRepresentation)
618
0
{
619
0
    CSF_VS result = valueScale;
620
621
0
    switch (cellRepresentation)
622
0
    {
623
0
        case CR_UINT1:
624
0
        {
625
0
            switch (valueScale)
626
0
            {
627
0
                case VS_LDD:
628
0
                {
629
0
                    result = VS_LDD;
630
0
                    break;
631
0
                }
632
0
                default:
633
0
                {
634
0
                    result = VS_BOOLEAN;
635
0
                    break;
636
0
                }
637
0
            }
638
0
            break;
639
0
        }
640
0
        case CR_INT4:
641
0
        {
642
0
            switch (valueScale)
643
0
            {
644
0
                case VS_BOOLEAN:
645
0
                {
646
0
                    result = VS_NOMINAL;
647
0
                    break;
648
0
                }
649
0
                case VS_SCALAR:
650
0
                {
651
0
                    result = VS_ORDINAL;
652
0
                    break;
653
0
                }
654
0
                case VS_DIRECTION:
655
0
                {
656
0
                    result = VS_ORDINAL;
657
0
                    break;
658
0
                }
659
0
                case VS_LDD:
660
0
                {
661
0
                    result = VS_NOMINAL;
662
0
                    break;
663
0
                }
664
0
                default:
665
0
                {
666
0
                    result = valueScale;
667
0
                    break;
668
0
                }
669
0
            }
670
0
            break;
671
0
        }
672
0
        case CR_REAL4:
673
0
        {
674
0
            switch (valueScale)
675
0
            {
676
0
                case VS_DIRECTION:
677
0
                {
678
0
                    result = VS_DIRECTION;
679
0
                    break;
680
0
                }
681
0
                default:
682
0
                {
683
0
                    result = VS_SCALAR;
684
0
                    break;
685
0
                }
686
0
            }
687
0
            break;
688
0
        }
689
0
        default:
690
0
        {
691
0
            break;
692
0
        }
693
0
    }
694
695
0
    return result;
696
0
}
697
698
void castValuesToBooleanRange(void *buffer, size_t size,
699
                              CSF_CR cellRepresentation)
700
0
{
701
0
    switch (cellRepresentation)
702
0
    {
703
        // CSF version 2.
704
        // ----------------------------------------------------------
705
0
        case (CR_UINT1):
706
0
        {
707
0
            std::for_each(static_cast<UINT1 *>(buffer),
708
0
                          static_cast<UINT1 *>(buffer) + size,
709
0
                          CastToBooleanRange<UINT1>());
710
0
            break;
711
0
        }
712
0
        case (CR_INT4):
713
0
        {
714
0
            std::for_each(static_cast<INT4 *>(buffer),
715
0
                          static_cast<INT4 *>(buffer) + size,
716
0
                          CastToBooleanRange<INT4>());
717
0
            break;
718
0
        }
719
0
        case (CR_REAL4):
720
0
        {
721
0
            std::for_each(static_cast<REAL4 *>(buffer),
722
0
                          static_cast<REAL4 *>(buffer) + size,
723
0
                          CastToBooleanRange<REAL4>());
724
0
            break;
725
0
        }
726
0
        case (CR_REAL8):
727
0
        {
728
0
            std::for_each(static_cast<REAL8 *>(buffer),
729
0
                          static_cast<REAL8 *>(buffer) + size,
730
0
                          CastToBooleanRange<REAL8>());
731
0
            break;
732
0
        }
733
        // CSF version 1.
734
        // ----------------------------------------------------------
735
0
        case CR_INT1:
736
0
        {
737
0
            std::for_each(static_cast<INT1 *>(buffer),
738
0
                          static_cast<INT1 *>(buffer) + size,
739
0
                          CastToBooleanRange<INT1>());
740
0
            break;
741
0
        }
742
0
        case CR_INT2:
743
0
        {
744
0
            std::for_each(static_cast<INT2 *>(buffer),
745
0
                          static_cast<INT2 *>(buffer) + size,
746
0
                          CastToBooleanRange<INT2>());
747
0
            break;
748
0
        }
749
0
        case CR_UINT2:
750
0
        {
751
0
            std::for_each(static_cast<UINT2 *>(buffer),
752
0
                          static_cast<UINT2 *>(buffer) + size,
753
0
                          CastToBooleanRange<UINT2>());
754
0
            break;
755
0
        }
756
0
        case CR_UINT4:
757
0
        {
758
0
            std::for_each(static_cast<UINT4 *>(buffer),
759
0
                          static_cast<UINT4 *>(buffer) + size,
760
0
                          CastToBooleanRange<UINT4>());
761
0
            break;
762
0
        }
763
0
        default:
764
0
        {
765
0
            CPLAssert(false);
766
0
            break;
767
0
        }
768
0
    }
769
0
}
770
771
void castValuesToDirectionRange(void *buffer, size_t size)
772
0
{
773
0
    std::for_each(static_cast<REAL4 *>(buffer),
774
0
                  static_cast<REAL4 *>(buffer) + size, CastToDirection());
775
0
}
776
777
void castValuesToLddRange(void *buffer, size_t size)
778
0
{
779
0
    std::for_each(static_cast<UINT1 *>(buffer),
780
0
                  static_cast<UINT1 *>(buffer) + size, CastToLdd());
781
0
}