Skip to content

Commit 718dcef

Browse files
committed
enhancement intel#149 implemented: access half-precision floating point data as single float
Motivation: half-precision floating point format is used to minimize storage and traffic mostly. Application level manipulates with single and double precision usually. So, two routines added to public API to encode/decode given single precision value in the half precision format
1 parent d75f2eb commit 718dcef

10 files changed

+370
-13
lines changed

Makefile

+2
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,9 @@ TINYCBOR_FREESTANDING_SOURCES = \
2626
src/cborerrorstrings.c \
2727
src/cborencoder.c \
2828
src/cborencoder_close_container_checked.c \
29+
src/cborencoder_float.c \
2930
src/cborparser.c \
31+
src/cborparser_float.c \
3032
src/cborpretty.c \
3133
#
3234
CBORDUMP_SOURCES = tools/cbordump/cbordump.c

Makefile.nmake

+4
Original file line numberDiff line numberDiff line change
@@ -5,17 +5,21 @@ TINYCBOR_SOURCES = \
55
src\cborerrorstrings.c \
66
src\cborencoder.c \
77
src\cborencoder_close_container_checked.c \
8+
src\cborencoder_float.c \
89
src\cborparser.c \
910
src\cborparser_dup_string.c \
11+
src\cborparser_float.c \
1012
src\cborpretty.c \
1113
src\cborpretty_stdio.c \
1214
src\cborvalidation.c
1315
TINYCBOR_OBJS = \
1416
src\cborerrorstrings.obj \
1517
src\cborencoder.obj \
1618
src\cborencoder_close_container_checked.obj \
19+
src\cborencoder_float.obj \
1720
src\cborparser.obj \
1821
src\cborparser_dup_string.obj \
22+
src\cborparser_float.obj \
1923
src\cborpretty.obj \
2024
src\cborpretty_stdio.obj \
2125
src\cborvalidation.obj

src/cbor.h

+3
Original file line numberDiff line numberDiff line change
@@ -237,6 +237,7 @@ CBOR_INLINE_API CborError cbor_encode_undefined(CborEncoder *encoder)
237237

238238
CBOR_INLINE_API CborError cbor_encode_half_float(CborEncoder *encoder, const void *value)
239239
{ return cbor_encode_floating_point(encoder, CborHalfFloatType, value); }
240+
CBOR_API CborError cbor_encode_float_as_half_float(CborEncoder *encoder, float value);
240241
CBOR_INLINE_API CborError cbor_encode_float(CborEncoder *encoder, float value)
241242
{ return cbor_encode_floating_point(encoder, CborFloatType, &value); }
242243
CBOR_INLINE_API CborError cbor_encode_double(CborEncoder *encoder, double value)
@@ -492,7 +493,9 @@ CBOR_API CborError cbor_value_map_find_value(const CborValue *map, const char *s
492493
/* Floating point */
493494
CBOR_INLINE_API bool cbor_value_is_half_float(const CborValue *value)
494495
{ return value->type == CborHalfFloatType; }
496+
CBOR_PRIVATE_API uint16_t _cbor_value_get_half_float_helper(const CborValue *value);
495497
CBOR_API CborError cbor_value_get_half_float(const CborValue *value, void *result);
498+
CBOR_API CborError cbor_value_get_half_float_as_float(const CborValue *value, float *result);
496499

497500
CBOR_INLINE_API bool cbor_value_is_float(const CborValue *value)
498501
{ return value->type == CborFloatType; }

src/cborencoder.c

+15-3
Original file line numberDiff line numberDiff line change
@@ -382,7 +382,7 @@ CborError cbor_encode_simple_value(CborEncoder *encoder, uint8_t value)
382382
* This function is useful for code that needs to pass through floating point
383383
* values but does not wish to have the actual floating-point code.
384384
*
385-
* \sa cbor_encode_half_float, cbor_encode_float, cbor_encode_double
385+
* \sa cbor_encode_half_float, cbor_encode_float_as_half_float, cbor_encode_float, cbor_encode_double
386386
*/
387387
CborError cbor_encode_floating_point(CborEncoder *encoder, CborType fpType, const void *value)
388388
{
@@ -589,13 +589,25 @@ CborError cbor_encoder_close_container(CborEncoder *encoder, const CborEncoder *
589589
* \sa cbor_encode_floating_point(), cbor_encode_float(), cbor_encode_double()
590590
*/
591591

592+
/**
593+
* \fn CborError cbor_encode_float_as_half_float(CborEncoder *encoder, float value)
594+
*
595+
* Convert the IEEE 754 single-precision (32-bit) floating point value \a value
596+
* to the IEEE 754 half-precision (16-bit) floating point value and append it
597+
* to the CBOR stream provided by \a encoder.
598+
* The \a value should be in the range of the IEEE 754 half-precision floating point type,
599+
* INFINITY, -INFINITY, or NAN, otherwise the behavior of this function is undefined.
600+
*
601+
* \sa cbor_encode_floating_point(), cbor_encode_float(), cbor_encode_double()
602+
*/
603+
592604
/**
593605
* \fn CborError cbor_encode_float(CborEncoder *encoder, float value)
594606
*
595607
* Appends the IEEE 754 single-precision (32-bit) floating point value \a value
596608
* to the CBOR stream provided by \a encoder.
597609
*
598-
* \sa cbor_encode_floating_point(), cbor_encode_half_float(), cbor_encode_double()
610+
* \sa cbor_encode_floating_point(), cbor_encode_half_float(), cbor_encode_float_as_half_float(), cbor_encode_double()
599611
*/
600612

601613
/**
@@ -604,7 +616,7 @@ CborError cbor_encoder_close_container(CborEncoder *encoder, const CborEncoder *
604616
* Appends the IEEE 754 double-precision (64-bit) floating point value \a value
605617
* to the CBOR stream provided by \a encoder.
606618
*
607-
* \sa cbor_encode_floating_point(), cbor_encode_half_float(), cbor_encode_float()
619+
* \sa cbor_encode_floating_point(), cbor_encode_half_float(), cbor_encode_float_as_half_float(), cbor_encode_float()
608620
*/
609621

610622
/**

src/cborencoder_float.c

+42
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
/****************************************************************************
2+
**
3+
** Break Copyright (C) 2019
4+
**
5+
** Permission is hereby granted, free of charge, to any person obtaining a copy
6+
** of this software and associated documentation files (the "Software"), to deal
7+
** in the Software without restriction, including without limitation the rights
8+
** to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
** copies of the Software, and to permit persons to whom the Software is
10+
** furnished to do so, subject to the following conditions:
11+
**
12+
** The above copyright notice and this permission notice shall be included in
13+
** all copies or substantial portions of the Software.
14+
**
15+
** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
** IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
** FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
** AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
** LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
** OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21+
** THE SOFTWARE.
22+
**
23+
****************************************************************************/
24+
25+
#define _BSD_SOURCE 1
26+
#define _DEFAULT_SOURCE 1
27+
#ifndef __STDC_LIMIT_MACROS
28+
# define __STDC_LIMIT_MACROS 1
29+
#endif
30+
31+
#include "cbor.h"
32+
33+
#include "cborinternal_p.h"
34+
35+
#ifndef CBOR_NO_HALF_FLOAT_TYPE
36+
CborError cbor_encode_float_as_half_float(CborEncoder *encoder, float value)
37+
{
38+
uint16_t v = (uint16_t)encode_half(value);
39+
40+
return cbor_encode_floating_point(encoder, CborHalfFloatType, &v);
41+
}
42+
#endif

src/cborparser.c

+19-4
Original file line numberDiff line numberDiff line change
@@ -1414,17 +1414,32 @@ CborError cbor_value_map_find_value(const CborValue *map, const char *string, Cb
14141414
* floating point, this function takes a \c{void *} as a parameter for the
14151415
* storage area, which must be at least 16 bits wide.
14161416
*
1417-
* \sa cbor_value_get_type(), cbor_value_is_valid(), cbor_value_is_half_float(), cbor_value_get_float()
1417+
* \sa cbor_value_get_type(), cbor_value_is_valid(), cbor_value_is_half_float(), cbor_value_get_half_float_as_float(), cbor_value_get_float()
14181418
*/
14191419
CborError cbor_value_get_half_float(const CborValue *value, void *result)
14201420
{
14211421
uint16_t v;
1422-
cbor_assert(cbor_value_is_half_float(value));
14231422

1424-
/* size has been computed already */
1425-
v = get16(value->ptr + 1);
1423+
v = _cbor_value_get_half_float_helper(value);
14261424
memcpy(result, &v, sizeof(v));
1425+
14271426
return CborNoError;
14281427
}
14291428

1429+
/** \internal
1430+
*
1431+
* Retrieves the CBOR half-precision floating point value binary
1432+
* representation as 16-bit unsigned integer.
1433+
* The result can be used as-is, e.g. to copy bitwise into the
1434+
* system-dependent half-precision floating point type, or it can be
1435+
* converted to the C language standard floating point type
1436+
* (float or double).
1437+
*/
1438+
CBOR_PRIVATE_API uint16_t _cbor_value_get_half_float_helper(const CborValue *value)
1439+
{
1440+
cbor_assert(cbor_value_is_half_float(value));
1441+
/* size has been computed already */
1442+
return get16(value->ptr + 1);
1443+
}
1444+
14301445
/** @} */

src/cborparser_float.c

+54
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
/****************************************************************************
2+
**
3+
** Break Copyright (C) 2019
4+
**
5+
** Permission is hereby granted, free of charge, to any person obtaining a copy
6+
** of this software and associated documentation files (the "Software"), to deal
7+
** in the Software without restriction, including without limitation the rights
8+
** to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
** copies of the Software, and to permit persons to whom the Software is
10+
** furnished to do so, subject to the following conditions:
11+
**
12+
** The above copyright notice and this permission notice shall be included in
13+
** all copies or substantial portions of the Software.
14+
**
15+
** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
** IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
** FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
** AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
** LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
** OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21+
** THE SOFTWARE.
22+
**
23+
****************************************************************************/
24+
25+
#define _BSD_SOURCE 1
26+
#define _DEFAULT_SOURCE 1
27+
#ifndef __STDC_LIMIT_MACROS
28+
# define __STDC_LIMIT_MACROS 1
29+
#endif
30+
31+
#include "cbor.h"
32+
33+
#include "cborinternal_p.h"
34+
35+
#ifndef CBOR_NO_HALF_FLOAT_TYPE
36+
/**
37+
* Retrieves the CBOR half-precision floating point (16-bit) value that \a
38+
* value points to, converts it to the float and store it in \a result.
39+
* If the iterator \a value does not point to a half-precision floating
40+
* point value, the behavior is undefined, so checking with \ref
41+
* cbor_value_get_type or with \ref cbor_value_is_half_float is recommended.
42+
* \sa cbor_value_get_type(), cbor_value_is_valid(), cbor_value_is_half_float(), cbor_value_get_half_float(), cbor_value_get_float()
43+
*/
44+
CborError cbor_value_get_half_float_as_float(const CborValue *value, float *result)
45+
{
46+
uint16_t v;
47+
48+
v = _cbor_value_get_half_float_helper(value);
49+
50+
*result = (float)decode_half((unsigned short)v);
51+
52+
return CborNoError;
53+
}
54+
#endif

tests/cpp/tst_cpp.cpp

+2
Original file line numberDiff line numberDiff line change
@@ -23,9 +23,11 @@
2323
****************************************************************************/
2424

2525
#include "../../src/cborencoder.c"
26+
#include "../../src/cborencoder_float.c"
2627
#include "../../src/cborerrorstrings.c"
2728
#include "../../src/cborparser.c"
2829
#include "../../src/cborparser_dup_string.c"
30+
#include "../../src/cborparser_float.c"
2931
#include "../../src/cborvalidation.c"
3032

3133
#include <QtTest>

0 commit comments

Comments
 (0)