STIR 6.4.0
write_data.inl
Go to the documentation of this file.
1/*
2 Copyright (C) 2004 - 2008, Hammersmith Imanet Ltd
3 This file is part of STIR.
4
5 SPDX-License-Identifier: Apache-2.0
6
7 See STIR/LICENSE.txt for details
8*/
17#include "stir/Array.h"
18#include "stir/convert_array.h"
19#include "stir/NumericType.h"
20#include "stir/NumericInfo.h"
21#include "stir/ByteOrder.h"
22#include "stir/Succeeded.h"
25#include "stir/warning.h"
26#include <typeinfo>
27
28START_NAMESPACE_STIR
29
30namespace detail
31{
32/* Generic implementation of write_data_with_fixed_scale_factor().
33 See test_if_1d.h for info why we do this this way.
34*/
35template <int num_dimensions, class OStreamT, class elemT, class OutputType, class ScaleT>
36inline Succeeded
37write_data_with_fixed_scale_factor_help(is_not_1d,
38 OStreamT& s,
39 const ArrayType<num_dimensions, elemT>& data,
40 NumericInfo<OutputType> output_type,
41 const ScaleT scale_factor,
42 const ByteOrder byte_order,
43 const bool can_corrupt_data)
44{
45 for (auto iter = data.begin(); iter != data.end(); ++iter)
46 {
47 if (write_data_with_fixed_scale_factor(s, *iter, output_type, scale_factor, byte_order, can_corrupt_data) == Succeeded::no)
48 return Succeeded::no;
49 }
50 return Succeeded::yes;
51}
52
53// specialisation for 1D case
54template <class OStreamT, class elemT, class OutputType, class ScaleT>
55inline Succeeded
56write_data_with_fixed_scale_factor_help(is_1d,
57 OStreamT& s,
58 const ArrayType<1, elemT>& data,
59 NumericInfo<OutputType>,
60 const ScaleT scale_factor,
61 const ByteOrder byte_order,
62 const bool can_corrupt_data)
63{
64 if (typeid(OutputType) != typeid(elemT) || scale_factor != 1)
65 {
66 ScaleT new_scale_factor = scale_factor;
67 auto data_tmp = convert_array(new_scale_factor, data, NumericInfo<OutputType>());
68 if (std::fabs(new_scale_factor - scale_factor) > scale_factor * .001)
69 return Succeeded::no;
70 return write_data_1d(s, data_tmp, byte_order, /*can_corrupt_data*/ true);
71 }
72 else
73 {
74 return write_data_1d(s, data, byte_order, can_corrupt_data);
75 }
76}
77
78} // end of namespace detail
79
80template <int num_dimensions, class OStreamT, class elemT, class OutputType, class ScaleT>
81Succeeded
84 NumericInfo<OutputType> output_type,
85 const ScaleT scale_factor,
86 const ByteOrder byte_order,
87 const bool can_corrupt_data)
88{
89 return detail::write_data_with_fixed_scale_factor_help(
90 detail::test_if_1d<num_dimensions>(), s, data, output_type, scale_factor, byte_order, can_corrupt_data);
91}
92
93template <int num_dimensions, class OStreamT, class elemT, class OutputType, class ScaleT>
94Succeeded
95write_data(OStreamT& s,
97 NumericInfo<OutputType> output_type,
98 ScaleT& scale_factor,
99 const ByteOrder byte_order,
100 const bool can_corrupt_data)
101{
102 find_scale_factor(scale_factor, data, NumericInfo<OutputType>());
103 return write_data_with_fixed_scale_factor(s, data, output_type, scale_factor, byte_order, can_corrupt_data);
104}
105
106template <int num_dimensions, class OStreamT, class elemT>
107inline Succeeded
108write_data(OStreamT& s, const ArrayType<num_dimensions, elemT>& data, const ByteOrder byte_order, const bool can_corrupt_data)
109{
110 return write_data_with_fixed_scale_factor(s, data, NumericInfo<elemT>(), 1.F, byte_order, can_corrupt_data);
111}
112
113template <int num_dimensions, class OStreamT, class elemT, class ScaleT>
114Succeeded
115write_data(OStreamT& s,
118 ScaleT& scale,
119 const ByteOrder byte_order,
120 const bool can_corrupt_data)
121{
122 if (NumericInfo<elemT>().type_id() == type)
123 {
124 // you might want to use the scale even in this case,
125 // but at the moment we don't
126 scale = ScaleT(1);
127 return write_data(s, data, byte_order, can_corrupt_data);
128 }
129 switch (type.id)
130 {
131 // define macro what to do with a specific NumericType
132#define CASE(NUMERICTYPE) \
133 case NUMERICTYPE: \
134 return write_data(s, data, NumericInfo<typename TypeForNumericType<NUMERICTYPE>::type>(), scale, byte_order, can_corrupt_data)
135
136 // now list cases that we want
137 CASE(NumericType::SCHAR);
138 CASE(NumericType::UCHAR);
139 CASE(NumericType::SHORT);
140 CASE(NumericType::USHORT);
141 CASE(NumericType::INT);
142 CASE(NumericType::UINT);
143 CASE(NumericType::LONG);
144 CASE(NumericType::ULONG);
145 CASE(NumericType::FLOAT);
146 CASE(NumericType::DOUBLE);
147#undef CASE
148 default:
149 warning("write_data : type not yet supported\n, at line %d in file %s", __LINE__, __FILE__);
150 return Succeeded::no;
151 }
152}
153
154END_NAMESPACE_STIR
defines the stir::Array class for multi-dimensional (numeric) arrays
This file declares the stir::ByteOrder class.
This file declares the class stir::NumericInfo.
This file declares the stir::NumericType class.
Declaration of class stir::Succeeded.
This class provides member functions to find out what byte-order your machine is and to swap numbers.
Definition ByteOrder.h:100
class NumericInfo<NUMBER> defines properties for the type NUMBER.
Definition NumericInfo.h:68
provides names for some numeric types and methods for finding their properties.
Definition NumericType.h:55
This file declares the stir::convert_array functions. This is a function to convert stir::Array objec...
Succeeded write_data_1d(std::ostream &s, const Array< num_dimensions, elemT > &data, const ByteOrder byte_order, const bool can_corrupt_data)
This is an internal function called by write_data(). It does the actual writing to std::ostream.
Definition write_data_1d.inl:33
Succeeded write_data_with_fixed_scale_factor(OStreamT &s, const ArrayType< num_dimensions, elemT > &data, NumericInfo< OutputType > output_type, const ScaleT scale_factor, const ByteOrder byte_order=ByteOrder::native, const bool can_corrupt_data=false)
Write the data of an Array to file as a different type but using a given scale factor.
Definition write_data.inl:82
Succeeded write_data(OStreamT &s, const ArrayType< num_dimensions, elemT > &data, const ByteOrder byte_order=ByteOrder::native, const bool can_corrupt_data=false)
Write the data of an Array to file.
Definition write_data.inl:108
void find_scale_factor(scaleT &scale_factor, const Array< num_dimensions, T1 > &data_in, const NumericInfo< T2 > info_for_out_type)
A function that finds a scale factor to use when converting data to a new type.
Definition convert_array.inl:28
Array< num_dimensions, T2 > convert_array(scaleT &scale_factor, const Array< num_dimensions, T1 > &data_in, const NumericInfo< T2 > info2)
A function that returns a new Array (of the same dimension) with elements of type T2.
Definition convert_array.inl:35
void warning(const char *const s,...)
Print warning with format string a la printf.
Definition warning.cxx:41
Array< num_dimensions, elemT > ArrayType
type alias for future-proofing for "large" rectangular arrays
Definition ArrayFwd.h:25
a templated class used to check if it's a 1D array or not This class only exists to allow a work-arou...
Definition test_if_1d.h:71
Classes for use in implementation of stir::Array, stir::BasicCoordinate etc to test if it's a 1D arra...
Declaration of stir::warning()
Declaration of stir::write_data_1d() functions for writing 1D stir::Array objects to file.