1 /* 2 * Copyright 2004-2007, Haiku, Inc. All rights reserved. 3 * Distributed under the terms of the MIT License. 4 */ 5 #ifndef READ_HELPER_H 6 #define READ_HELPER_H 7 8 9 #include "TIFF.h" 10 11 #include <BufferIO.h> 12 #include <ByteOrder.h> 13 14 15 template<class T> 16 inline void 17 byte_swap(T &/*data*/) 18 { 19 // Specialize for data types which actually swap 20 // printf("DEAD MEAT!\n"); 21 // exit(1); 22 } 23 24 25 template<> 26 inline void 27 byte_swap(float &data) 28 { 29 data = __swap_float(data); 30 } 31 32 33 template<> 34 inline void 35 byte_swap(int32 &data) 36 { 37 data = __swap_int32(data); 38 } 39 40 41 template<> 42 inline void 43 byte_swap(uint32 &data) 44 { 45 data = __swap_int32(data); 46 } 47 48 49 template<> 50 inline void 51 byte_swap(int16 &data) 52 { 53 data = __swap_int16(data); 54 } 55 56 57 template<> 58 inline void 59 byte_swap(uint16 &data) 60 { 61 data = __swap_int16(data); 62 } 63 64 65 class TReadHelper { 66 public: 67 TReadHelper(BPositionIO& stream) 68 : 69 fStream(&stream, 65536, false), 70 fError(B_OK), 71 fSwap(false) 72 { 73 } 74 75 template<class T> inline void 76 operator()(T &data) 77 { 78 fError = fStream.Read((void *)&data, sizeof(T)); 79 if (fError > B_OK) { 80 if (IsSwapping()) 81 byte_swap(data); 82 return; 83 } 84 85 if (fError == 0) 86 fError = B_ERROR; 87 throw fError; 88 } 89 90 template<class T> inline void 91 operator()(T data, size_t length) 92 { 93 fError = fStream.Read((void *)data, length); 94 if (fError < (ssize_t)length) 95 fError = B_ERROR; 96 97 if (fError >= B_OK) 98 return; 99 100 throw fError; 101 } 102 103 template<class T> inline T 104 Next() 105 { 106 T value; 107 fError = fStream.Read((void *)&value, sizeof(T)); 108 if (fError > B_OK) { 109 if (IsSwapping()) 110 byte_swap(value); 111 return value; 112 } 113 114 if (fError == 0) 115 fError = B_ERROR; 116 throw fError; 117 } 118 119 inline uint32 120 Next(uint16 type) 121 { 122 if (type == TIFF_UINT16_TYPE || type == TIFF_INT16_TYPE) 123 return Next<uint16>(); 124 125 return Next<uint32>(); 126 } 127 128 inline double 129 NextDouble(uint16 type) 130 { 131 switch (type) { 132 case TIFF_UINT16_TYPE: 133 return Next<uint16>(); 134 case TIFF_UINT32_TYPE: 135 return Next<uint32>(); 136 case TIFF_UFRACTION_TYPE: 137 { 138 double value = Next<uint32>(); 139 return value / Next<uint32>(); 140 } 141 case TIFF_INT16_TYPE: 142 return Next<int16>(); 143 case TIFF_INT32_TYPE: 144 return Next<int32>(); 145 case TIFF_FRACTION_TYPE: 146 { 147 double value = Next<int32>(); 148 return value / Next<int32>(); 149 } 150 case TIFF_FLOAT_TYPE: 151 return Next<float>(); 152 case TIFF_DOUBLE_TYPE: 153 return Next<double>(); 154 155 default: 156 return Next<uint8>(); 157 } 158 } 159 160 inline void 161 NextShorts(uint16* data, size_t length) 162 { 163 fError = fStream.Read(data, length); 164 if (fError < (ssize_t)length) 165 fError = B_ERROR; 166 167 if (fError >= B_OK) { 168 if (IsSwapping()) 169 swap_data(B_INT16_TYPE, data, length, B_SWAP_ALWAYS); 170 return; 171 } 172 173 throw fError; 174 } 175 176 status_t Status() const 177 { return fError >= B_OK ? B_OK : fError; }; 178 179 off_t Seek(off_t offset, int32 mode) 180 { return fStream.Seek(offset, mode); } 181 off_t Position() const 182 { return fStream.Position(); } 183 184 void SetSwap(bool yesNo) { fSwap = yesNo; }; 185 bool IsSwapping() const { return fSwap; }; 186 187 BPositionIO& Stream() { return fStream; } 188 189 private: 190 BBufferIO fStream; 191 status_t fError; 192 bool fSwap; 193 }; 194 195 #endif // READ_HELPER_H 196