00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #ifndef ARCHON_UTILITIES_IMAGE_DATA_H
00021 #define ARCHON_UTILITIES_IMAGE_DATA_H
00022
00023 #include <inttypes.h>
00024
00025 #include <cmath>
00026 #include <vector>
00027 #include <stdexcept>
00028
00029 #include <archon/math/functions.H>
00030 #include <archon/util/memory.H>
00031 #include <archon/util/pixel_format.H>
00032
00033 namespace Archon
00034 {
00035 namespace Utilities
00036 {
00037 using namespace std;
00038
00039
00204 struct ImageData
00205 {
00206 struct BufferFormat
00207 {
00212 bool rightToLeft;
00213
00218 bool topToBottom;
00219
00224 bool verticalStrips;
00225
00234 bool wordAlignStrip;
00235
00236 BufferFormat(bool rightToLeft = false, bool topToBottom = false,
00237 bool verticalStrips = false, bool wordAlignStrip = false):
00238 rightToLeft(rightToLeft), topToBottom(topToBottom),
00239 verticalStrips(verticalStrips), wordAlignStrip(wordAlignStrip) {}
00240 };
00241
00242
00302 ImageData(void *buffer, int numberOfStrips, int pixelsPerStrip,
00303 const PixelFormat &pixelFormat = PixelFormat(),
00304 const BufferFormat &bufferFormat = BufferFormat(),
00305 int left = 0, int bottom = 0, int width = 0, int height = 0,
00306 const vector<bool> &endianness = vector<bool>())
00307 throw(PixelFormat::UnsupportedWordTypeException,
00308 PixelFormat::InconsistencyException, invalid_argument);
00309
00310
00311
00326 void queryPixelMap(double x, double y, long double *pixel,
00327 int horizontalRepeat = 0, int verticalRepeat = 0) const
00328 {
00329
00330 x = x * interestWidth - 0.5;
00331 y = y * interestHeight - 0.5;
00332
00333
00334
00335 long xi = static_cast<long>(floor(x));
00336 long yi = static_cast<long>(floor(y));
00337
00338
00339 int n = numberOfChannels;
00340 Array<long double> c0(n), c1(n), c2(n), c3(n);
00341 getPixel(xi, yi, c0.get(), horizontalRepeat, verticalRepeat);
00342 getPixel(xi+1, yi, c1.get(), horizontalRepeat, verticalRepeat);
00343 getPixel(xi, yi+1, c2.get(), horizontalRepeat, verticalRepeat);
00344 getPixel(xi+1, yi+1, c3.get(), horizontalRepeat, verticalRepeat);
00345
00346
00347 long double xf1 = x - xi;
00348 long double yf1 = y - yi;
00349 long double xf0 = 1 - xf1;
00350 long double yf0 = 1 - yf1;
00351
00352
00353
00354
00355 long double w0 = xf0 * yf0;
00356 long double w1 = xf1 * yf0;
00357 long double w2 = xf0 * yf1;
00358 long double w3 = xf1 * yf1;
00359
00360
00361 for(int i=0; i<n; ++i)
00362 pixel[i] = w0 * c0[i] + w1 * c1[i] + w2 * c2[i] + w3 * c3[i];
00363 }
00364
00365
00375 void getPixel(long x, long y, long double *pixel,
00376 int horizontalRepeat = 0, int verticalRepeat = 0) const
00377 {
00378
00379 if(0 < horizontalRepeat) Math::clamp<long>(x, 0, interestWidth * horizontalRepeat - 1);
00380 if(0 < verticalRepeat) Math::clamp<long>(y, 0, interestHeight * verticalRepeat - 1);
00381
00382
00383 x = Math::modulo<long>(x, interestWidth);
00384 y = Math::modulo<long>(y, interestHeight);
00385
00386
00387 if(rightToLeft) x = interestWidth-1 - x;
00388 if(topToBottom) y = interestHeight-1 - y;
00389 if(verticalStrips) swap(x, y);
00390
00391
00392 long bitOffset = principalBitOffset + x * bitsPerPixel + y * bitsPerStrip;
00393 cerr << "ImageData::getPixel: bit offset: " << bitOffset << endl;
00394
00395
00396 long wordOffset;
00397 bitOffset = Math::modulo<long>(bitOffset, bitsPerWord, wordOffset);
00398
00399 decodePixelSequence(buffer + wordOffset * bytesPerWord, bitOffset, 1, pixel);
00400 }
00401
00402
00403 private:
00404
00426 void decodePixelSequence(const char *data, int wordBitOffest, long n, long double *pixels) const;
00427
00428
00453 void unpackPixelSequence(const char *data, int wordBitOffest, long n, long double *pixels) const;
00454
00460 template<typename T> inline void
00461 unpackPixelSequenceDirectInteger(const char *data, long n,
00462 long double *pixels) const;
00463
00469 template<typename T> inline void
00470 unpackPixelSequenceDirectFloat(const char *data, long n,
00471 long double *pixels) const;
00472
00480 PixelFormat::MaxInt readIntegerWord(const char *data) const
00481 {
00482 if(bytePermutation.empty()) switch(wordType)
00483 {
00484 case PixelFormat::std_char: return *reinterpret_cast<const unsigned char *>(data);
00485 case PixelFormat::std_short: return *reinterpret_cast<const unsigned short *>(data);
00486 case PixelFormat::std_int: return *reinterpret_cast<const unsigned int *>(data);
00487 case PixelFormat::std_long: return *reinterpret_cast<const unsigned long *>(data);
00488 case PixelFormat::std_max_int: return *reinterpret_cast<const PixelFormat::MaxInt *>(data);
00489 default: return 0;
00490 }
00491
00492
00493 switch(wordType)
00494 {
00495 case PixelFormat::std_char: return readWithBytePermutation< unsigned char >(data, bytePermutation);
00496 case PixelFormat::std_short: return readWithBytePermutation< unsigned short >(data, bytePermutation);
00497 case PixelFormat::std_int: return readWithBytePermutation< unsigned int >(data, bytePermutation);
00498 case PixelFormat::std_long: return readWithBytePermutation< unsigned long >(data, bytePermutation);
00499 case PixelFormat::std_max_int: return readWithBytePermutation< PixelFormat::MaxInt >(data, bytePermutation);
00500 default: return 0;
00501 }
00502 }
00503
00504 char *buffer;
00505 bool rightToLeft;
00506 bool topToBottom;
00507 bool verticalStrips;
00508 int interestWidth;
00509 int interestHeight;
00510
00511
00512
00513
00514
00515 PixelFormat::FormatType pixelFormatType;
00516 PixelFormat::WordType wordType;
00517
00518 int bytesPerWord;
00519 int bitsPerWord;
00520
00528 vector<int> bytePermutation;
00529
00530 bool mostSignificantBitsFirst;
00531
00532 int numberOfChannels;
00533
00534
00535 struct MemoryField
00536 {
00537 int channelIndex;
00538 int bitWidth;
00539 PixelFormat::MaxInt bitMask;
00540 long double min;
00541 long double max;
00542
00543 MemoryField(int channelIndex = -1, int bitWidth = 0):
00544 channelIndex(channelIndex), bitWidth(bitWidth),
00545
00546 bitMask((static_cast<PixelFormat::MaxInt>(1)<<bitWidth-1<<1)-1),
00547 min(0), max(1) {}
00548 };
00549
00555 vector<MemoryField> memoryFields;
00556
00557
00561 long bitsPerPixel;
00562
00566 long bitsPerStrip;
00567
00579 long principalBitOffset;
00580 };
00581 }
00582 }
00583
00584 #endif // ARCHON_UTILITIES_IMAGE_DATA_H