blob: c9dbe3e4b3a9d1f1df7f113bc8ba9906d390cfc2 (
plain) (
blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
|
/* See LICENSE file for copyright and license details. */
#include "common.h"
/**
* Just an arbitrary version
*/
#define ANY bits64
/**
* Allocate and initalise a gamma ramp with any depth
*
* @param ramps_sys Output gamma ramps
* @param ramps The gamma ramps whose sizes should be duplicated
* @param depth The depth of the gamma ramps to allocate,
* `-1` for `float`, `-2` for `double`
* @param elements Output reference for the grand size of the gamma ramps
* @return Zero on success, otherwise (negative) the value of an
* error identifier provided by this library
*/
int
libgamma_internal_allocated_any_ramp(union gamma_ramps_any *restrict ramps_sys, const union gamma_ramps_any *restrict ramps,
signed depth, size_t *restrict elements)
{
/* Calculate the size of the allocation to do */
size_t d, n = ramps->ANY.red_size;
if (n > SIZE_MAX - ramps->ANY.green_size) {
goto enomem;
}
n += ramps->ANY.green_size;
if (n > SIZE_MAX - ramps->ANY.blue_size) {
enomem:
errno = ENOMEM;
return LIBGAMMA_ERRNO_SET;
}
n += ramps->ANY.blue_size;
switch (depth) {
case 8: d = sizeof(uint8_t); break;
case 16: d = sizeof(uint16_t); break;
case 32: d = sizeof(uint32_t); break;
case 64: d = sizeof(uint64_t); break;
case -1: d = sizeof(float); break;
case -2: d = sizeof(double); break;
default:
errno = EINVAL;
return LIBGAMMA_ERRNO_SET;
}
/* Copy the gamma ramp sizes */
ramps_sys->ANY = ramps->ANY;
/* Allocate the new ramps */
if (!n) {
ramps_sys->ANY.red = NULL;
ramps_sys->ANY.green = NULL;
ramps_sys->ANY.blue = NULL;
*elements = n;
return 0;
}
#ifdef HAVE_LIBGAMMA_METHOD_LINUX_DRM
/* Valgrind complains about us reading uninitialize memory if we just use malloc */
ramps_sys->ANY.red = calloc(n, d);
#else
if (n > SIZE_MAX / d)
goto enomem;
ramps_sys->ANY.red = malloc(n * d);
#endif
ramps_sys->ANY.green = (void *)&((char *)ramps_sys->ANY. red)[ramps->ANY. red_size * d / sizeof(char)];
ramps_sys->ANY.blue = (void *)&((char *)ramps_sys->ANY.green)[ramps->ANY.green_size * d / sizeof(char)];
/* Report the total gamma ramp size */
*elements = n;
/* Report successfulness */
return ramps_sys->ANY.red ? 0 : LIBGAMMA_ERRNO_SET;
}
|