Add scaling converters and secondary converters.

Scaling converters scale, as the name implies.

The two wrapping converters, map & ranged sanitize
data for sending to V4L2, either converting a value
to be within a map, or within a range, respectively.
(These are intended for use with V4L2 int menu and int
controls, respectively).

TEST: Unit tests pass
BUG: 30140438
Change-Id: Ie7d86118e00c0b59e6457fc16449228706098952
diff --git a/modules/camera/3_4/Android.mk b/modules/camera/3_4/Android.mk
index 4c77968..820a993 100644
--- a/modules/camera/3_4/Android.mk
+++ b/modules/camera/3_4/Android.mk
@@ -55,8 +55,10 @@
   metadata/enum_converter_test.cpp \
   metadata/fixed_property_test.cpp \
   metadata/ignored_control_test.cpp \
+  metadata/map_converter_test.cpp \
   metadata/metadata_test.cpp \
   metadata/optioned_control_test.cpp \
+  metadata/ranged_converter_test.cpp \
   metadata/v4l2_enum_control_test.cpp \
 
 # V4L2 Camera HAL.
diff --git a/modules/camera/3_4/metadata/converter_interface.h b/modules/camera/3_4/metadata/converter_interface.h
index 38ede00..ca6a0f2 100644
--- a/modules/camera/3_4/metadata/converter_interface.h
+++ b/modules/camera/3_4/metadata/converter_interface.h
@@ -22,14 +22,14 @@
 namespace v4l2_camera_hal {
 
 // A ConverterInterface converts metadata values to V4L2 values vice-versa.
-template <typename T_metadata, typename T_V4L2>
+template <typename TMetadata, typename TV4L2>
 class ConverterInterface {
  public:
   virtual ~ConverterInterface(){};
 
   // Convert.
-  virtual int MetadataToV4L2(T_metadata value, T_V4L2* conversion) = 0;
-  virtual int V4L2ToMetadata(T_V4L2 value, T_metadata* conversion) = 0;
+  virtual int MetadataToV4L2(TMetadata value, TV4L2* conversion) = 0;
+  virtual int V4L2ToMetadata(TV4L2 value, TMetadata* conversion) = 0;
 };
 
 }  // namespace v4l2_camera_hal
diff --git a/modules/camera/3_4/metadata/converter_interface_mock.h b/modules/camera/3_4/metadata/converter_interface_mock.h
new file mode 100644
index 0000000..3f7e6f7
--- /dev/null
+++ b/modules/camera/3_4/metadata/converter_interface_mock.h
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+// Mock for converter interfaces.
+
+#ifndef V4L2_CAMERA_HAL_METADATA_CONVERTER_INTERFACE_MOCK_H_
+#define V4L2_CAMERA_HAL_METADATA_CONVERTER_INTERFACE_MOCK_H_
+
+#include <gmock/gmock.h>
+
+#include "converter_interface.h"
+
+namespace v4l2_camera_hal {
+
+template <typename TMetadata, typename TV4L2>
+class ConverterInterfaceMock : public ConverterInterface<TMetadata, TV4L2> {
+ public:
+  ConverterInterfaceMock(){};
+  MOCK_METHOD2_T(MetadataToV4L2, int(TMetadata, TV4L2*));
+  MOCK_METHOD2_T(V4L2ToMetadata, int(TV4L2, TMetadata*));
+};
+
+}  // namespace v4l2_camera_hal
+
+#endif  // V4L2_CAMERA_HAL_METADATA_CONVERTER_INTERFACE_MOCK_H_
diff --git a/modules/camera/3_4/metadata/map_converter.h b/modules/camera/3_4/metadata/map_converter.h
new file mode 100644
index 0000000..b1734b5
--- /dev/null
+++ b/modules/camera/3_4/metadata/map_converter.h
@@ -0,0 +1,139 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef V4L2_CAMERA_HAL_METADATA_MAP_CONVERTER_H_
+#define V4L2_CAMERA_HAL_METADATA_MAP_CONVERTER_H_
+
+#include <errno.h>
+
+#include <map>
+#include <memory>
+
+#include "../common.h"
+#include "converter_interface.h"
+
+namespace v4l2_camera_hal {
+
+// A MapConverter fits values converted by a wrapped converter
+// to a map entry corresponding to the key with the nearest value.
+template <typename TMetadata, typename TV4L2, typename TMapKey>
+class MapConverter : public ConverterInterface<TMetadata, TV4L2> {
+ public:
+  MapConverter(
+      std::shared_ptr<ConverterInterface<TMetadata, TMapKey>> wrapped_converter,
+      std::map<TMapKey, TV4L2> conversion_map);
+
+  virtual int MetadataToV4L2(TMetadata value, TV4L2* conversion) override;
+  virtual int V4L2ToMetadata(TV4L2 value, TMetadata* conversion) override;
+
+ private:
+  std::shared_ptr<ConverterInterface<TMetadata, TMapKey>> wrapped_converter_;
+  std::map<TMapKey, TV4L2> conversion_map_;
+
+  DISALLOW_COPY_AND_ASSIGN(MapConverter);
+};
+
+// -----------------------------------------------------------------------------
+
+template <typename TMetadata, typename TV4L2, typename TMapKey>
+MapConverter<TMetadata, TV4L2, TMapKey>::MapConverter(
+    std::shared_ptr<ConverterInterface<TMetadata, TMapKey>> wrapped_converter,
+    std::map<TMapKey, TV4L2> conversion_map)
+    : wrapped_converter_(std::move(wrapped_converter)),
+      conversion_map_(conversion_map) {
+  HAL_LOG_ENTER();
+}
+
+template <typename TMetadata, typename TV4L2, typename TMapKey>
+int MapConverter<TMetadata, TV4L2, TMapKey>::MetadataToV4L2(TMetadata value,
+                                                            TV4L2* conversion) {
+  HAL_LOG_ENTER();
+
+  if (conversion_map_.empty()) {
+    HAL_LOGE("Empty conversion map.");
+    return -EINVAL;
+  }
+
+  TMapKey raw_conversion = 0;
+  int res = wrapped_converter_->MetadataToV4L2(value, &raw_conversion);
+  if (res) {
+    HAL_LOGE("Failed to perform underlying conversion.");
+    return res;
+  }
+
+  // Find nearest key.
+  auto kv = conversion_map_.lower_bound(raw_conversion);
+  // lower_bound finds the first >= element.
+  if (kv == conversion_map_.begin()) {
+    // Searching for less than the smallest key, so that will be the nearest.
+    *conversion = kv->second;
+  } else if (kv == conversion_map_.end()) {
+    // Searching for greater than the largest key, so that will be the nearest.
+    --kv;
+    *conversion = kv->second;
+  } else {
+    // Since kv points to the first >= element, either that or the previous
+    // element will be nearest.
+    *conversion = kv->second;
+    TMapKey diff = kv->first - raw_conversion;
+
+    // Now compare to the previous. This element will be < raw conversion,
+    // so reverse the order of the subtraction.
+    --kv;
+    if (raw_conversion - kv->first < diff) {
+      *conversion = kv->second;
+    }
+  }
+
+  return 0;
+}
+
+template <typename TMetadata, typename TV4L2, typename TMapKey>
+int MapConverter<TMetadata, TV4L2, TMapKey>::V4L2ToMetadata(
+    TV4L2 value, TMetadata* conversion) {
+  HAL_LOG_ENTER();
+
+  // Unfortunately no bi-directional map lookup in C++.
+  // Breaking on second, not first found so that a warning
+  // can be given if there are multiple values.
+  size_t count = 0;
+  int res;
+  for (auto kv : conversion_map_) {
+    if (kv.second == value) {
+      ++count;
+      if (count == 1) {
+        // First match.
+        res = wrapped_converter_->V4L2ToMetadata(kv.first, conversion);
+      } else {
+        // second match.
+        break;
+      }
+    }
+  }
+
+  if (count == 0) {
+    HAL_LOGE("Couldn't find map conversion of V4L2 value %d.", value);
+    return -EINVAL;
+  } else if (count > 1) {
+    HAL_LOGW("Multiple map conversions found for V4L2 value %d, using first.",
+             value);
+  }
+  return res;
+}
+
+}  // namespace v4l2_camera_hal
+
+#endif  // V4L2_CAMERA_HAL_METADATA_MAP_CONVERTER_H_
diff --git a/modules/camera/3_4/metadata/map_converter_test.cpp b/modules/camera/3_4/metadata/map_converter_test.cpp
new file mode 100644
index 0000000..0361810
--- /dev/null
+++ b/modules/camera/3_4/metadata/map_converter_test.cpp
@@ -0,0 +1,110 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "map_converter.h"
+
+#include <gmock/gmock.h>
+#include <gtest/gtest.h>
+
+#include "converter_interface_mock.h"
+
+using testing::Return;
+using testing::SetArgPointee;
+using testing::Test;
+using testing::_;
+
+namespace v4l2_camera_hal {
+
+class MapConverterTest : public Test {
+ protected:
+  virtual void SetUp() {
+    converter_.reset(new ConverterInterfaceMock<int, int32_t>());
+    dut_.reset(new MapConverter<int, int32_t, int32_t>(converter_, map_));
+  }
+
+  virtual void ExpectConvertToV4L2(int32_t converted, int32_t expected) {
+    int initial = 99;
+    EXPECT_CALL(*converter_, MetadataToV4L2(initial, _))
+        .WillOnce(DoAll(SetArgPointee<1>(converted), Return(0)));
+
+    int32_t actual = expected + 1;  // Initialize to non-expected value.
+    ASSERT_EQ(dut_->MetadataToV4L2(initial, &actual), 0);
+    EXPECT_EQ(actual, expected);
+  }
+
+  std::shared_ptr<ConverterInterfaceMock<int, int32_t>> converter_;
+  std::unique_ptr<MapConverter<int, int32_t, int32_t>> dut_;
+
+  const std::map<int32_t, int32_t> map_{{10, 1}, {40, 4}, {20, 2}, {30, 3}};
+};
+
+TEST_F(MapConverterTest, NormalConversionToV4L2) {
+  // A value that matches the map perfectly.
+  auto kv = map_.begin();
+  ExpectConvertToV4L2(kv->first, kv->second);
+}
+
+TEST_F(MapConverterTest, RoundingDownConversionToV4L2) {
+  // A value that's in range but not an exact key value.
+  auto kv = map_.begin();
+  ExpectConvertToV4L2(kv->first + 1, kv->second);
+}
+
+TEST_F(MapConverterTest, RoundingUpConversionToV4L2) {
+  // A value that's in range but not an exact key value.
+  auto kv = map_.begin();
+  ++kv;
+  ExpectConvertToV4L2(kv->first - 1, kv->second);
+}
+
+TEST_F(MapConverterTest, ClampUpConversionToV4L2) {
+  // A value that's below range.
+  auto kv = map_.begin();
+  ExpectConvertToV4L2(kv->first - 1, kv->second);
+}
+
+TEST_F(MapConverterTest, ClampDownConversionToV4L2) {
+  // A value that's above range (even after fitting to step).
+  auto kv = map_.rbegin();
+  ExpectConvertToV4L2(kv->first + 1, kv->second);
+}
+
+TEST_F(MapConverterTest, ConversionErrorToV4L2) {
+  int initial = 99;
+  int err = -99;
+  EXPECT_CALL(*converter_, MetadataToV4L2(initial, _)).WillOnce(Return(err));
+
+  int32_t unused;
+  EXPECT_EQ(dut_->MetadataToV4L2(initial, &unused), err);
+}
+
+TEST_F(MapConverterTest, NormalConversionToMetadata) {
+  auto kv = map_.begin();
+  int expected = 99;
+  EXPECT_CALL(*converter_, V4L2ToMetadata(kv->first, _))
+      .WillOnce(DoAll(SetArgPointee<1>(expected), Return(0)));
+
+  int actual = expected + 1;  // Initialize to non-expected value.
+  ASSERT_EQ(dut_->V4L2ToMetadata(kv->second, &actual), 0);
+  EXPECT_EQ(actual, expected);
+}
+
+TEST_F(MapConverterTest, NotFoundConversionToMetadata) {
+  int unused;
+  ASSERT_EQ(dut_->V4L2ToMetadata(100, &unused), -EINVAL);
+}
+
+}  // namespace v4l2_camera_hal
diff --git a/modules/camera/3_4/metadata/ranged_converter.h b/modules/camera/3_4/metadata/ranged_converter.h
new file mode 100644
index 0000000..115ac2a
--- /dev/null
+++ b/modules/camera/3_4/metadata/ranged_converter.h
@@ -0,0 +1,102 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef V4L2_CAMERA_HAL_METADATA_RANGED_CONVERTER_H_
+#define V4L2_CAMERA_HAL_METADATA_RANGED_CONVERTER_H_
+
+#include <memory>
+
+#include "../common.h"
+#include "converter_interface.h"
+
+namespace v4l2_camera_hal {
+
+// An RangedConverter fits values converted by a wrapped converter
+// to a stepped range (when going from metadata -> v4l2. The other
+// direction remains unchanged).
+template <typename TMetadata, typename TV4L2>
+class RangedConverter : public ConverterInterface<TMetadata, TV4L2> {
+ public:
+  RangedConverter(
+      std::shared_ptr<ConverterInterface<TMetadata, TV4L2>> wrapped_converter,
+      TV4L2 min,
+      TV4L2 max,
+      TV4L2 step);
+
+  virtual int MetadataToV4L2(TMetadata value, TV4L2* conversion) override;
+  virtual int V4L2ToMetadata(TV4L2 value, TMetadata* conversion) override;
+
+ private:
+  std::shared_ptr<ConverterInterface<TMetadata, TV4L2>> wrapped_converter_;
+  const TV4L2 min_;
+  const TV4L2 max_;
+  const TV4L2 step_;
+
+  DISALLOW_COPY_AND_ASSIGN(RangedConverter);
+};
+
+// -----------------------------------------------------------------------------
+
+template <typename TMetadata, typename TV4L2>
+RangedConverter<TMetadata, TV4L2>::RangedConverter(
+    std::shared_ptr<ConverterInterface<TMetadata, TV4L2>> wrapped_converter,
+    TV4L2 min,
+    TV4L2 max,
+    TV4L2 step)
+    : wrapped_converter_(std::move(wrapped_converter)),
+      min_(min),
+      max_(max),
+      step_(step) {
+  HAL_LOG_ENTER();
+}
+
+template <typename TMetadata, typename TV4L2>
+int RangedConverter<TMetadata, TV4L2>::MetadataToV4L2(TMetadata value,
+                                                      TV4L2* conversion) {
+  HAL_LOG_ENTER();
+
+  TV4L2 raw_conversion = 0;
+  int res = wrapped_converter_->MetadataToV4L2(value, &raw_conversion);
+  if (res) {
+    HAL_LOGE("Failed to perform underlying conversion.");
+    return res;
+  }
+
+  // Round down to step (steps start at min_).
+  raw_conversion -= (raw_conversion - min_) % step_;
+
+  // Clamp to range.
+  if (raw_conversion < min_) {
+    raw_conversion = min_;
+  } else if (raw_conversion > max_) {
+    raw_conversion = max_;
+  }
+
+  *conversion = raw_conversion;
+  return 0;
+}
+
+template <typename TMetadata, typename TV4L2>
+int RangedConverter<TMetadata, TV4L2>::V4L2ToMetadata(TV4L2 value,
+                                                      TMetadata* conversion) {
+  HAL_LOG_ENTER();
+
+  return wrapped_converter_->V4L2ToMetadata(value, conversion);
+}
+
+}  // namespace v4l2_camera_hal
+
+#endif  // V4L2_CAMERA_HAL_METADATA_RANGED_CONVERTER_H_
diff --git a/modules/camera/3_4/metadata/ranged_converter_test.cpp b/modules/camera/3_4/metadata/ranged_converter_test.cpp
new file mode 100644
index 0000000..2b5ccc6
--- /dev/null
+++ b/modules/camera/3_4/metadata/ranged_converter_test.cpp
@@ -0,0 +1,86 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "ranged_converter.h"
+
+#include <gmock/gmock.h>
+#include <gtest/gtest.h>
+
+#include "converter_interface_mock.h"
+
+using testing::Return;
+using testing::SetArgPointee;
+using testing::Test;
+using testing::_;
+
+namespace v4l2_camera_hal {
+
+class RangedConverterTest : public Test {
+ protected:
+  virtual void SetUp() {
+    converter_.reset(new ConverterInterfaceMock<int, int32_t>());
+    dut_.reset(
+        new RangedConverter<int, int32_t>(converter_, min_, max_, step_));
+  }
+
+  virtual void ExpectConvert(int32_t converted, int32_t expected) {
+    int initial = 99;
+    EXPECT_CALL(*converter_, MetadataToV4L2(initial, _))
+        .WillOnce(DoAll(SetArgPointee<1>(converted), Return(0)));
+
+    int32_t actual = expected + 1;  // Initialize to non-expected value.
+    ASSERT_EQ(dut_->MetadataToV4L2(initial, &actual), 0);
+    EXPECT_EQ(actual, expected);
+  }
+
+  std::shared_ptr<ConverterInterfaceMock<int, int32_t>> converter_;
+  std::unique_ptr<RangedConverter<int, int32_t>> dut_;
+
+  const int32_t min_ = -11;
+  const int32_t max_ = 10;
+  const int32_t step_ = 3;
+};
+
+TEST_F(RangedConverterTest, NormalConversion) {
+  // A value that's in range and on step.
+  ExpectConvert(max_ - step_, max_ - step_);
+}
+
+TEST_F(RangedConverterTest, RoundingConversion) {
+  // A value that's in range but off step.
+  ExpectConvert(max_ - step_ + 1, max_ - step_);
+}
+
+TEST_F(RangedConverterTest, ClampUpConversion) {
+  // A value that's below range.
+  ExpectConvert(min_ - 1, min_);
+}
+
+TEST_F(RangedConverterTest, ClampDownConversion) {
+  // A value that's above range (even after fitting to step).
+  ExpectConvert(max_ + step_, max_);
+}
+
+TEST_F(RangedConverterTest, ConversionError) {
+  int initial = 99;
+  int err = -99;
+  EXPECT_CALL(*converter_, MetadataToV4L2(initial, _)).WillOnce(Return(err));
+
+  int32_t unused;
+  EXPECT_EQ(dut_->MetadataToV4L2(initial, &unused), err);
+}
+
+}  // namespace v4l2_camera_hal
diff --git a/modules/camera/3_4/metadata/scaling_converter.h b/modules/camera/3_4/metadata/scaling_converter.h
new file mode 100644
index 0000000..42b08a7
--- /dev/null
+++ b/modules/camera/3_4/metadata/scaling_converter.h
@@ -0,0 +1,76 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef V4L2_CAMERA_HAL_METADATA_SCALING_CONVERTER_H_
+#define V4L2_CAMERA_HAL_METADATA_SCALING_CONVERTER_H_
+
+#include "../common.h"
+#include "converter_interface.h"
+
+namespace v4l2_camera_hal {
+
+// An ScalingConverter scales values up or down.
+template <typename TMetadata, typename TV4L2>
+class ScalingConverter : public ConverterInterface<TMetadata, TV4L2> {
+ public:
+  ScalingConverter(TMetadata v4l2_to_metadata_numerator,
+                   TMetadata v4l2_to_metadata_denominator);
+
+  virtual int MetadataToV4L2(TMetadata value, TV4L2* conversion) override;
+  virtual int V4L2ToMetadata(TV4L2 value, TMetadata* conversion) override;
+
+ private:
+  const TMetadata v4l2_to_metadata_numerator_;
+  const TMetadata v4l2_to_metadata_denominator_;
+
+  DISALLOW_COPY_AND_ASSIGN(ScalingConverter);
+};
+
+// -----------------------------------------------------------------------------
+
+template <typename TMetadata, typename TV4L2>
+ScalingConverter<TMetadata, TV4L2>::ScalingConverter(
+    TMetadata v4l2_to_metadata_numerator,
+    TMetadata v4l2_to_metadata_denominator)
+    : v4l2_to_metadata_numerator_(v4l2_to_metadata_numerator),
+      v4l2_to_metadata_denominator_(v4l2_to_metadata_denominator),
+{
+  HAL_LOG_ENTER();
+}
+
+template <typename TMetadata, typename TV4L2>
+int ScalingConverter<TMetadata, TV4L2>::MetadataToV4L2(TMetadata value,
+                                                       TV4L2* conversion) {
+  HAL_LOG_ENTER();
+
+  *conversion = static_cast<TV4L2>(value * v4l2_to_metadata_denominator_ /
+                                   v4l2_to_metadata_numerator_);
+  return 0;
+}
+
+template <typename TMetadata, typename TV4L2>
+int ScalingConverter<TMetadata, TV4L2>::V4L2ToMetadata(TV4L2 value,
+                                                       TMetadata* conversion) {
+  HAL_LOG_ENTER();
+
+  *conversion = static_cast<TMetadata>(value) * v4l2_to_metadata_numerator_ /
+                v4l2_to_metadata_denominator_;
+  return 0;
+}
+
+}  // namespace v4l2_camera_hal
+
+#endif  // V4L2_CAMERA_HAL_METADATA_SCALING_CONVERTER_H_