summaryrefslogtreecommitdiffstats
path: root/media/img_utils/include/img_utils/EndianUtils.h
diff options
context:
space:
mode:
Diffstat (limited to 'media/img_utils/include/img_utils/EndianUtils.h')
-rw-r--r--media/img_utils/include/img_utils/EndianUtils.h250
1 files changed, 250 insertions, 0 deletions
diff --git a/media/img_utils/include/img_utils/EndianUtils.h b/media/img_utils/include/img_utils/EndianUtils.h
new file mode 100644
index 0000000..e99be1a
--- /dev/null
+++ b/media/img_utils/include/img_utils/EndianUtils.h
@@ -0,0 +1,250 @@
+/*
+ * Copyright 2014 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 IMG_UTILS_ENDIAN_UTILS
+#define IMG_UTILS_ENDIAN_UTILS
+
+#include <img_utils/Output.h>
+
+#include <cutils/compiler.h>
+#include <utils/Errors.h>
+#include <stdint.h>
+#include <endian.h>
+#include <assert.h>
+
+namespace android {
+namespace img_utils {
+
+/**
+ * Endianness types supported.
+ */
+enum ANDROID_API Endianness {
+ UNDEFINED_ENDIAN, // Default endianness will be used.
+ BIG,
+ LITTLE
+};
+
+/**
+ * Convert from the native device endianness to big endian.
+ */
+template<typename T>
+T convertToBigEndian(T in);
+
+/**
+ * Convert from the native device endianness to little endian.
+ */
+template<typename T>
+T convertToLittleEndian(T in);
+
+/**
+ * A utility class for writing to an Output with the given endianness.
+ */
+class ANDROID_API EndianOutput : public Output {
+ public:
+ /**
+ * Wrap the given Output. Calling write methods will result in
+ * writes to this output.
+ */
+ EndianOutput(Output* out, Endianness end=LITTLE);
+
+ virtual ~EndianOutput();
+
+ /**
+ * Call open on the wrapped output.
+ */
+ virtual status_t open();
+
+ /**
+ * Call close on the wrapped output.
+ */
+ virtual status_t close();
+
+ /**
+ * Set the endianness to use when writing.
+ */
+ virtual void setEndianness(Endianness end);
+
+ /**
+ * Get the currently configured endianness.
+ */
+ virtual Endianness getEndianness() const;
+
+ /**
+ * Get the current number of bytes written by this EndianOutput.
+ */
+ virtual uint32_t getCurrentOffset() const;
+
+
+ // TODO: switch write methods to uint32_t instead of size_t,
+ // the max size of a TIFF files is bounded
+
+ /**
+ * The following methods will write elements from given input buffer to the output.
+ * Count elements in the buffer will be written with the endianness set for this
+ * EndianOutput. If the given offset is greater than zero, that many elements will
+ * be skipped in the buffer before writing.
+ *
+ * Returns OK on success, or a negative error code.
+ */
+ virtual status_t write(const uint8_t* buf, size_t offset, size_t count);
+
+ virtual status_t write(const int8_t* buf, size_t offset, size_t count);
+
+ virtual status_t write(const uint16_t* buf, size_t offset, size_t count);
+
+ virtual status_t write(const int16_t* buf, size_t offset, size_t count);
+
+ virtual status_t write(const uint32_t* buf, size_t offset, size_t count);
+
+ virtual status_t write(const int32_t* buf, size_t offset, size_t count);
+
+ virtual status_t write(const uint64_t* buf, size_t offset, size_t count);
+
+ virtual status_t write(const int64_t* buf, size_t offset, size_t count);
+
+ virtual status_t write(const float* buf, size_t offset, size_t count);
+
+ virtual status_t write(const double* buf, size_t offset, size_t count);
+
+ protected:
+ template<typename T>
+ inline status_t writeHelper(const T* buf, size_t offset, size_t count);
+
+ uint32_t mOffset;
+ Output* mOutput;
+ Endianness mEndian;
+};
+
+template<typename T>
+inline status_t EndianOutput::writeHelper(const T* buf, size_t offset, size_t count) {
+ assert(offset <= count);
+ status_t res = OK;
+ size_t size = sizeof(T);
+ switch(mEndian) {
+ case BIG: {
+ for (size_t i = offset; i < count; ++i) {
+ T tmp = convertToBigEndian<T>(buf[offset + i]);
+ if ((res = mOutput->write(reinterpret_cast<uint8_t*>(&tmp), 0, size))
+ != OK) {
+ return res;
+ }
+ mOffset += size;
+ }
+ break;
+ }
+ case LITTLE: {
+ for (size_t i = offset; i < count; ++i) {
+ T tmp = convertToLittleEndian<T>(buf[offset + i]);
+ if ((res = mOutput->write(reinterpret_cast<uint8_t*>(&tmp), 0, size))
+ != OK) {
+ return res;
+ }
+ mOffset += size;
+ }
+ break;
+ }
+ default: {
+ return BAD_VALUE;
+ }
+ }
+ return res;
+}
+
+template<>
+inline uint8_t convertToBigEndian(uint8_t in) {
+ return in;
+}
+
+template<>
+inline int8_t convertToBigEndian(int8_t in) {
+ return in;
+}
+
+template<>
+inline uint16_t convertToBigEndian(uint16_t in) {
+ return htobe16(in);
+}
+
+template<>
+inline int16_t convertToBigEndian(int16_t in) {
+ return htobe16(in);
+}
+
+template<>
+inline uint32_t convertToBigEndian(uint32_t in) {
+ return htobe32(in);
+}
+
+template<>
+inline int32_t convertToBigEndian(int32_t in) {
+ return htobe32(in);
+}
+
+template<>
+inline uint64_t convertToBigEndian(uint64_t in) {
+ return htobe64(in);
+}
+
+template<>
+inline int64_t convertToBigEndian(int64_t in) {
+ return htobe64(in);
+}
+
+template<>
+inline uint8_t convertToLittleEndian(uint8_t in) {
+ return in;
+}
+
+template<>
+inline int8_t convertToLittleEndian(int8_t in) {
+ return in;
+}
+
+template<>
+inline uint16_t convertToLittleEndian(uint16_t in) {
+ return htole16(in);
+}
+
+template<>
+inline int16_t convertToLittleEndian(int16_t in) {
+ return htole16(in);
+}
+
+template<>
+inline uint32_t convertToLittleEndian(uint32_t in) {
+ return htole32(in);
+}
+
+template<>
+inline int32_t convertToLittleEndian(int32_t in) {
+ return htole32(in);
+}
+
+template<>
+inline uint64_t convertToLittleEndian(uint64_t in) {
+ return htole64(in);
+}
+
+template<>
+inline int64_t convertToLittleEndian(int64_t in) {
+ return htole64(in);
+}
+
+} /*namespace img_utils*/
+} /*namespace android*/
+
+#endif /*IMG_UTILS_ENDIAN_UTILS*/
+