00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #include <map>
00021
00022 #include <archon/util/text.H>
00023 #include <archon/util/image_data.H>
00024
00025
00026 namespace Archon
00027 {
00028 namespace Utilities
00029 {
00030
00031
00032
00033
00034
00035
00036 ImageData::ImageData(void *buffer, int numberOfStrips, int pixelsPerStrip,
00037 const PixelFormat &pixelFormat,
00038 const BufferFormat &bufferFormat,
00039 int left, int bottom, int width, int height,
00040 const vector<bool> &endianness)
00041 throw(PixelFormat::UnsupportedWordTypeException,
00042 PixelFormat::InconsistencyException, invalid_argument):
00043 buffer(reinterpret_cast<char *>(buffer)),
00044 rightToLeft(bufferFormat.rightToLeft),
00045 topToBottom(bufferFormat.topToBottom),
00046 verticalStrips(bufferFormat.verticalStrips)
00047 {
00048 PixelFormat expandedPixelFormat = pixelFormat.getExpandedFormat();
00049
00050
00051 pixelFormatType = expandedPixelFormat.formatType;
00052
00053
00054 wordType = expandedPixelFormat.wordType;
00055 cerr << "ImageData::ImageData: word type: " << wordType << endl;
00056
00057
00058 bitsPerWord = expandedPixelFormat.bitsPerWord;
00059 cerr << "ImageData::ImageData: bits per word: " << bitsPerWord << endl;
00060 bytesPerWord = bitsPerWord / numeric_limits<unsigned char>::digits;
00061 cerr << "ImageData::ImageData: bytes per word: " << bytesPerWord << endl;
00062
00063
00064
00065
00066 {
00067 int levels = findMostSignificantBit(bytesPerWord);
00068 cerr << "ImageData::ImageData: byte order levels: " << levels << endl;
00069 if(!compareEndianness(endianness, vector<bool>(), levels))
00070 bytePermutation = computeBytePermutation(endianness, levels);
00071 if(bytePermutation.empty()) cerr << "ImageData::ImageData: Using native endianess" << endl;
00072 else
00073 {
00074 cerr << "ImageData::ImageData: byte reorder map:";
00075 for(int i=0; i<static_cast<int>(bytePermutation.size()); ++i) cerr << " " << bytePermutation[i];
00076 cerr << endl;
00077 }
00078 }
00079
00080 mostSignificantBitsFirst = expandedPixelFormat.mostSignificantBitsFirst;
00081
00082
00083 numberOfChannels = expandedPixelFormat.channelLayout.size();
00084
00085
00086 bitsPerPixel = pixelFormatType == PixelFormat::tight ? expandedPixelFormat.pixelSize : expandedPixelFormat.pixelSize * bitsPerWord;
00087
00088
00089 vector<int> memoryMap(pixelFormatType == PixelFormat::direct ? expandedPixelFormat.pixelSize : bitsPerPixel);
00090 for(int i=0; i<numberOfChannels; ++i) memoryMap[expandedPixelFormat.channelLayout[i].offset] = i;
00091 if(pixelFormatType == PixelFormat::direct)
00092 {
00093 for(int i=0; i<static_cast<int>(memoryMap.size()); ++i)
00094 {
00095 int j = memoryMap[i];
00096 if(j < 0)
00097 {
00098 memoryFields.push_back(MemoryField());
00099 continue;
00100 }
00101 memoryFields.push_back(MemoryField(j, expandedPixelFormat.channelLayout[j].width));
00102 }
00103 }
00104 else
00105 {
00106 int i=0;
00107 while(i < static_cast<int>(memoryMap.size()))
00108 {
00109 int j = -1;
00110 int w = 0;
00111
00112 while(i+w < static_cast<int>(memoryMap.size()) && memoryMap[i+w] < 0) ++w;
00113 if(!w)
00114 {
00115 j = memoryMap[i];
00116 w = expandedPixelFormat.channelLayout[j].width;
00117 }
00118 memoryFields.push_back(MemoryField(j, w));
00119 i += w;
00120 }
00121 }
00122 cerr << "ImageData::ImageData: pixel fields:";
00123 for(int i=0; i<static_cast<int>(memoryFields.size()); ++i)
00124 {
00125 cerr << " (" << memoryFields[i].channelIndex << ", " << memoryFields[i].bitWidth << ")";
00126 }
00127 cerr << endl;
00128
00129
00130
00131 {
00132 bitsPerStrip = bitsPerPixel * pixelsPerStrip;
00133 if(bufferFormat.wordAlignStrip)
00134 {
00135 long r = bitsPerStrip % bitsPerWord;
00136 if(r) bitsPerStrip += bitsPerWord-r;
00137 }
00138 cerr << "ImageData::ImageData: bits per strip: " << bitsPerStrip << endl;
00139 }
00140
00141
00142
00143 int fullWidth = verticalStrips ? numberOfStrips : pixelsPerStrip;
00144 int fullHeight = verticalStrips ? pixelsPerStrip : numberOfStrips;
00145 interestWidth = width ? width : fullWidth - left;
00146 interestHeight = height ? height : fullHeight - bottom;
00147 cerr << "ImageData::ImageData: width of interest frame: " << interestWidth << endl;
00148 cerr << "ImageData::ImageData: height of interest frame: " << interestHeight << endl;
00149
00150
00151
00152
00153
00154
00155
00156 {
00157 int x = rightToLeft ? fullWidth - interestWidth - left : left;
00158 int y = topToBottom ? fullHeight - interestHeight - bottom : bottom;
00159 if(verticalStrips) swap(x, y);
00160 principalBitOffset = x * bitsPerPixel + y * bitsPerStrip;
00161 cerr << "ImageData::ImageData: principal bit offset: " << principalBitOffset << endl;
00162 }
00163 }
00164
00170 template<typename T> inline void
00171 ImageData::unpackPixelSequenceDirectInteger(const char *data,
00172 long n,
00173 long double *pixels) const
00174 {
00175 int m = memoryFields.size();
00176 const T *p = reinterpret_cast<const T *>(data);
00177 for(int i=0; i<n; ++i)
00178 {
00179 for(int j=0; j<m; ++j)
00180 {
00181 const ImageData::MemoryField &f = memoryFields[j];
00182 if(f.channelIndex < 0) continue;
00183 PixelFormat::MaxInt v = p[j];
00184 if(mostSignificantBitsFirst) v >>= bitsPerWord-f.bitWidth;
00185 pixels[f.channelIndex] = static_cast<long double>(v & f.bitMask)/f.bitMask;
00186 }
00187 pixels += numberOfChannels;
00188 p += m;
00189 }
00190 }
00191
00197 template<typename T> inline void
00198 ImageData::unpackPixelSequenceDirectFloat(const char *data,
00199 long n,
00200 long double *pixels) const
00201 {
00202 int m = memoryFields.size();
00203 const T *p = reinterpret_cast<const T *>(data);
00204 for(int i=0; i<n; ++i)
00205 {
00206 for(int j=0; j<m; ++j)
00207 {
00208 const ImageData::MemoryField &f = memoryFields[j];
00209 if(f.channelIndex < 0) continue;
00210 pixels[f.channelIndex] = (static_cast<long double>(p[j])-f.min)/(f.max-f.min);
00211 }
00212 pixels += numberOfChannels;
00213 p += m;
00214 }
00215 }
00216
00217 void ImageData::decodePixelSequence(const char *data, int bitOffset,
00218 long n, long double *pixels) const
00219 {
00220 switch(pixelFormatType)
00221 {
00222 case PixelFormat::direct:
00223 switch(wordType)
00224 {
00225 case PixelFormat::std_char:
00226 unpackPixelSequenceDirectInteger<unsigned char>(data, n, pixels);
00227 return;
00228
00229 case PixelFormat::std_short:
00230 unpackPixelSequenceDirectInteger<unsigned short>(data, n, pixels);
00231 return;
00232
00233 case PixelFormat::std_int:
00234 unpackPixelSequenceDirectInteger<unsigned int>(data, n, pixels);
00235 return;
00236
00237 case PixelFormat::std_long:
00238 unpackPixelSequenceDirectInteger<unsigned long>(data, n, pixels);
00239 return;
00240
00241 case PixelFormat::std_max_int:
00242 unpackPixelSequenceDirectInteger<PixelFormat::MaxInt>(data, n, pixels);
00243 return;
00244
00245 case PixelFormat::std_float:
00246 unpackPixelSequenceDirectFloat<float>(data, n, pixels);
00247 return;
00248
00249 case PixelFormat::std_double:
00250 unpackPixelSequenceDirectFloat<double>(data, n, pixels);
00251 return;
00252
00253 case PixelFormat::std_long_double:
00254 unpackPixelSequenceDirectFloat<long double>(data, n, pixels);
00255 return;
00256
00257 default: return;
00258 }
00259
00260 default:
00261 unpackPixelSequence(data, bitOffset, n, pixels);
00262 }
00263 }
00264
00265 void ImageData::unpackPixelSequence(const char *data, int wordBitOffset,
00266 long n, long double *pixels) const
00267 {
00268 vector<MemoryField>::const_iterator field = memoryFields.end()-1;
00269
00270
00271 int bitAdvance = 0;
00272 for(;;)
00273 {
00274 if(field == memoryFields.end())
00275 {
00276 if(!--n) return;
00277 field = memoryFields.begin();
00278 }
00279 if(field->channelIndex < 0) bitAdvance += field->bitWidth;
00280 ++field;
00281 }
00282 long wordAdvance;
00283 wordBitOffset = Math::modulo(wordBitOffset + bitAdvance, bitsPerWord, wordAdvance);
00284 if(wordAdvance) data += bytesPerWord * wordAdvance;
00285
00286
00287 PixelFormat::MaxInt word = readIntegerWord(data);
00288
00289
00290 int channelBitWidth = field->bitWidth;
00291 int channelBitOffset = 0;
00292 PixelFormat::MaxInt channel = 0;
00293
00294
00295 for(;;)
00296 {
00297
00298 for(;;)
00299 {
00300
00301 int remainingWordBits = bitsPerWord - wordBitOffset;
00302 int remainingChannelBits = channelBitWidth - channelBitOffset;
00303
00304
00305 int m = min(remainingWordBits, remainingChannelBits);
00306
00307
00308
00309
00310 PixelFormat::MaxInt mask = (static_cast<PixelFormat::MaxInt>(1)<<m-1<<1) - 1;
00311 if(mostSignificantBitsFirst) channel |= (word>>remainingWordBits-m & mask) << remainingChannelBits-m;
00312 else channel |= (word>>wordBitOffset & mask) << channelBitOffset;
00313 channelBitOffset += m;
00314
00315
00316 if(channelBitWidth == channelBitOffset) break;
00317
00318
00319 if(m < remainingWordBits)
00320 {
00321 wordBitOffset += m;
00322 continue;
00323 }
00324
00325
00326 data += bytesPerWord;
00327 word = readIntegerWord(data);
00328 wordBitOffset = 0;
00329 }
00330
00331
00332 pixels[field->channelIndex] = static_cast<long double>(channel)/field->bitMask;
00333
00334
00335
00336 bitAdvance = 0;
00337 for(;;)
00338 {
00339 if(++field == memoryFields.end())
00340 {
00341 if(!--n) return;
00342 field = memoryFields.begin();
00343 }
00344 if(field->channelIndex < 0) bitAdvance += field->bitWidth;
00345 }
00346 if(bitAdvance)
00347 {
00348 wordBitOffset = Math::modulo(wordBitOffset + bitAdvance, bitsPerWord, wordAdvance);
00349 if(wordAdvance)
00350 {
00351 data += bytesPerWord * wordAdvance;
00352
00353
00354 word = readIntegerWord(data);
00355 }
00356 }
00357
00358
00359 channelBitWidth = field->bitWidth;
00360 channelBitOffset = 0;
00361 channel = 0;
00362 }
00363 }
00364 }
00365 }