TuttleOFX  1
ReaderInternal.h
Go to the documentation of this file.
00001 // -*- mode: C++; tab-width: 4 -*-
00002 // vi: ts=4
00003 
00004 /*
00005  * Copyright (c) 2009, Patrick A. Palmer.
00006  * All rights reserved.
00007  *
00008  * Redistribution and use in source and binary forms, with or without 
00009  * modification, are permitted provided that the following conditions are met:
00010  *
00011  *   - Redistributions of source code must retain the above copyright notice,
00012  *     this list of conditions and the following disclaimer.
00013  *
00014  *   - Redistributions in binary form must reproduce the above copyright
00015  *     notice, this list of conditions and the following disclaimer in the
00016  *     documentation and/or other materials provided with the distribution.
00017  *
00018  *   - Neither the name of Patrick A. Palmer nor the names of its
00019  *     contributors may be used to endorse or promote products derived from
00020  *     this software without specific prior written permission.
00021  *
00022  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
00023  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 
00024  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 
00025  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 
00026  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 
00027  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 
00028  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 
00029  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 
00030  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 
00031  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 
00032  * POSSIBILITY OF SUCH DAMAGE.
00033  */
00034 
00035 
00036 #ifndef _DPX_READERINTERNAL_H
00037 #define _DPX_READERINTERNAL_H 1
00038 
00039 
00040 #include <algorithm>
00041 #include "BaseTypeConverter.h"
00042 
00043 
00044 #define PADDINGBITS_10BITFILLEDMETHODA  2
00045 #define PADDINGBITS_10BITFILLEDMETHODB  0
00046 
00047 #define MASK_10BITPACKED                                0xffc0
00048 #define MULTIPLIER_10BITPACKED                  2
00049 #define REMAIN_10BITPACKED                              4
00050 #define REVERSE_10BITPACKED                             6
00051 
00052 #define MASK_12BITPACKED                                0xfff0
00053 #define MULTIPLIER_12BITPACKED                  4
00054 #define REMAIN_12BITPACKED                              2
00055 #define REVERSE_12BITPACKED                             4
00056 
00057 
00058 
00059 
00060 namespace dpx 
00061 {
00062 
00063         // this function is called when the DataSize is 10 bit and the packing method is kFilledMethodA or kFilledMethodB
00064         template<typename BUF, int PADDINGBITS>
00065         void Unfill10bitFilled(U32 *readBuf, const int x, BUF *data, int count, int bufoff, const int numberOfComponents)
00066         {
00067                 // unpack the words in the buffer
00068                 BUF *obuf = data + bufoff;
00069                 
00070                 int index = (x * sizeof(U32)) % numberOfComponents;
00071                 
00072                 for (int i = count - 1; i >= 0; i--)
00073                 {
00074                         // unpacking the buffer backwords
00075                         register U32 word = readBuf[(i + index) / 3 / sizeof(U32)];
00076                         register U16 d1 = U16(word >> ((2 - (i + index) % 3) * 10 + PADDINGBITS) & 0x3ff);
00077                         BaseTypeConvertU10ToU16(d1, d1);
00078                         BaseTypeConverter(d1, obuf[i]);
00079                 }
00080 #if 0
00081                 // NOTE: REVERSE -- is this something we really need to handle?
00082                 // There were many dpx images that write the components backwords
00083                 // because of some confusion with DPX v1 spec
00084                 
00085                 switch (dpxHeader.DatumSwap(element))
00086                 {
00087                         case 0:                 // no swap
00088                                 for (i = count - 1; i >= 0; i--)
00089                                 {
00090                                         U32 word = readBuf[(i + index) / 3 / sizeof(U32)];
00091                                         U16 d1 = U16(word >> (((i + index) % 3) * 10 + PADDINGBITS) & 0x3ff);
00092                                         BaseTypeConvertU10ToU16(d1, d1);
00093                                         BaseTypeConverter(d1, obuf[i]);
00094                                 }
00095                                 
00096                         case 1:                 // swap the three datum around so BGR becomes RGB
00097                                 for (i = count - 1; i >= 0; i--)
00098                                 {
00099                                         // unpacking the buffer backwords
00100                                         U32 word = readBuf[(i + index) / 3 / sizeof(U32)];
00101                                         U16 d1 = U16(word >> ((2 - (i + index) % 3) * 10 + PADDINGBITS) & 0x3ff);
00102                                         BaseTypeConvertU10ToU16(d1, d1);
00103                                         BaseTypeConverter(d1, obuf[i]);
00104                                 }
00105                                 
00106                                 // NOTE: NOT DONE case 2
00107                         case 2:                 // swap the second two of three datum around so YCrCb becomes YCbCr
00108                                 for (i = count - 1; i >= 0; i--)
00109                                 {
00110                                         // unpacking the buffer backwords
00111                                         U32 word = readBuf[(i + index) / 3 / sizeof(U32)];
00112                                         U16 d1 = U16(word >> ((2 - (count + index) % 3) * 10 + PADDINGBITS) & 0x3ff);
00113                                         BaseTypeConvertU10ToU16(d1, d1);
00114                                         BaseTypeConverter(d1, obuf[i]);
00115                                 }
00116                                 
00117                 }
00118 #endif          
00119         }
00120         
00121         template <typename IR, typename BUF, int PADDINGBITS>
00122         bool Read10bitFilled(const Header &dpxHeader, U32 *readBuf, IR *fd, const int element, const Block &block, BUF *data)
00123         {
00124                 // image height to read
00125                 const int height = block.y2 - block.y1 + 1;
00126 
00127                 // get the number of components for this element descriptor
00128                 const int numberOfComponents = dpxHeader.ImageElementComponentCount(element);
00129         
00130                 // end of line padding
00131                 int eolnPad = dpxHeader.EndOfLinePadding(element);
00132                 
00133                 // number of datums in one row
00134                 int datums = dpxHeader.Width() * numberOfComponents;
00135                 
00136                 // read in each line at a time directly into the user memory space
00137                 for (int line = 0; line < height; line++)
00138                 {
00139                         // determine offset into image element
00140 
00141                         int actline = line + block.y1;
00142 
00143                         // first get line offset
00144                         long offset = actline * datums;
00145                         
00146                         // add in the accumulated round-up offset - the following magical formula is
00147                         // just an unrolling of a loop that does the same work in constant time:
00148                         // for (int i = 1; i <= actline; ++i)
00149                         //     offset += (i * datums) % 3;
00150                         offset += datums % 3 * ((actline + 2) / 3) + (3 - datums % 3) % 3 * ((actline + 1) / 3);
00151                         
00152                         // round up to the 32-bit boundary
00153                         offset = offset / 3 * 4;
00154                         
00155                         // add in eoln padding
00156                         offset += line * eolnPad;
00157                         
00158                         // add in offset within the current line, rounding down so to catch any components within the word
00159                         offset += block.x1 * numberOfComponents / 3 * 4;
00160                         
00161                         
00162                         // get the read count in bytes, round to the 32-bit boundry
00163                         int readSize = (block.x2 - block.x1 + 1) * numberOfComponents;
00164                         readSize += readSize % 3;
00165                         readSize = readSize / 3 * 4;
00166                         
00167                         // determine buffer offset
00168                         int bufoff = line * datums;
00169         
00170                         fd->Read(dpxHeader, element, offset, readBuf, readSize);
00171         
00172                         // unpack the words in the buffer
00173 #if RLE_WORKING                 
00174                         int count = (block.x2 - block.x1 + 1) * numberOfComponents;
00175                         Unfill10bitFilled<BUF, PADDINGBITS>(readBuf, block.x1, data, count, bufoff, numberOfComponents);
00176 #else                                   
00177                         BUF *obuf = data + bufoff;
00178                         int index = (block.x1 * sizeof(U32)) % numberOfComponents;
00179 
00180                         for (int count = (block.x2 - block.x1 + 1) * numberOfComponents - 1; count >= 0; count--)
00181                         {
00182                                 // unpacking the buffer backwords
00183                                 U16 d1 = U16(readBuf[(count + index) / 3] >> ((2 - (count + index) % 3) * 10 + PADDINGBITS) & 0x3ff);
00184                                 BaseTypeConvertU10ToU16(d1, d1);
00185 
00186                                 BaseTypeConverter(d1, obuf[count]);
00187 
00188                                 // work-around for 1-channel DPX images - to swap the outlying pixels, otherwise the columns are in the wrong order
00189                                 if (numberOfComponents == 1 && count % 3 == 0)
00190                                         std::swap(obuf[count], obuf[count + 2]);
00191                         }
00192 #endif          
00193                 }
00194         
00195                 return true;
00196         }
00197 
00198 
00199         template <typename IR, typename BUF>
00200         bool Read10bitFilledMethodA(const Header &dpx, U32 *readBuf, IR *fd, const int element, const Block &block, BUF *data)
00201         {
00202                 // padding bits for PackedMethodA is 2
00203                 return Read10bitFilled<IR, BUF, PADDINGBITS_10BITFILLEDMETHODA>(dpx, readBuf, fd, element, block, data);
00204         }
00205 
00206 
00207         template <typename IR, typename BUF>
00208         bool Read10bitFilledMethodB(const Header &dpx, U32 *readBuf, IR *fd, const int element, const Block &block, BUF *data)
00209         {
00210                 return Read10bitFilled<IR, BUF, PADDINGBITS_10BITFILLEDMETHODB>(dpx, readBuf, fd, element, block, data);
00211         }
00212 
00213 
00214         // 10 bit, packed data
00215         // 12 bit, packed data
00216         template <typename BUF, U32 MASK, int MULTIPLIER, int REMAIN, int REVERSE>
00217         void UnPackPacked(U32 *readBuf, const int bitDepth, BUF *data, int count, int bufoff)
00218         {
00219                 // unpack the words in the buffer
00220                 BUF *obuf = data + bufoff;
00221                                 
00222                 for (int i = count - 1; i >= 0; i--)
00223                 {
00224                         // unpacking the buffer backwords
00225                         // find the byte that the data starts in, read in as a 16 bits then shift and mask
00226                         // the pattern with byte offset is:
00227                         //      10 bits datasize rotates every 4 data elements
00228                         //              element 0 -> 6 bit shift to normalize at MSB (10 LSB shifted 6 bits)
00229                         //              element 1 -> 4 bit shift to normalize at MSB
00230                         //              element 2 -> 2 bit shift to normalize at MSB
00231                         //              element 3 -> 0 bit shift to normalize at MSB
00232                         //  10 bit algorithm: (6-((count % 4)*2))
00233                         //      the pattern repeats every 160 bits
00234                         //      12 bits datasize rotates every 2 data elements
00235                         //              element 0 -> 4 bit shift to normalize at MSB
00236                         //              element 1 -> 0 bit shift to normalize at MSB
00237                         //  12 bit algorithm: (4-((count % 2)*4))
00238                         //      the pattern repeats every 96 bits
00239                         
00240                         // first determine the word that the data element completely resides in
00241                         U16 *d1 = reinterpret_cast<U16 *>(reinterpret_cast<U8 *>(readBuf)+((i * bitDepth) / 8 /*bits*/));
00242                         
00243                         // place the component in the MSB and mask it for both 10-bit and 12-bit
00244                         U16 d2 = (*d1 << (REVERSE - ((i % REMAIN) * MULTIPLIER))) & MASK;
00245                         
00246                         // For the 10/12 bit cases, specialize the 16-bit conversion by
00247                         // repacking into the LSB and using a specialized conversion
00248                         if(bitDepth == 10)
00249                         {
00250                                 d2 = d2 >> REVERSE;
00251                                 BaseTypeConvertU10ToU16(d2, d2);
00252                         }
00253                         else if(bitDepth == 12)
00254                         {
00255                                 d2 = d2 >> REVERSE;
00256                                 BaseTypeConvertU12ToU16(d2, d2);
00257                         }
00258                         
00259                         BaseTypeConverter(d2, obuf[i]);
00260                 }               
00261         }
00262 
00263         
00264         template <typename IR, typename BUF, U32 MASK, int MULTIPLIER, int REMAIN, int REVERSE>
00265         bool ReadPacked(const Header &dpxHeader, U32 *readBuf, IR *fd, const int element, const Block &block, BUF *data)
00266         {       
00267                 // image height to read
00268                 const int height = block.y2 - block.y1 + 1;
00269 
00270                 // get the number of components for this element descriptor
00271                 const int numberOfComponents = dpxHeader.ImageElementComponentCount(element);
00272 
00273                 // end of line padding
00274                 int eolnPad = dpxHeader.EndOfLinePadding(element);
00275 
00276                 // data size in bits
00277                 const int dataSize = dpxHeader.BitDepth(element);
00278 
00279                 // number of bytes 
00280                 const int lineSize = (dpxHeader.Width() * numberOfComponents * dataSize + 31) / 32;
00281 
00282                 // read in each line at a time directly into the user memory space
00283                 for (int line = 0; line < height; line++)
00284                 {
00285                         // determine offset into image element
00286                         long offset = (line + block.y1) * (lineSize * sizeof(U32)) +
00287                                                 (block.x1 * numberOfComponents * dataSize / 32 * sizeof(U32)) + (line * eolnPad);
00288         
00289                         // calculate read size
00290                         int readSize = ((block.x2 - block.x1 + 1) * numberOfComponents * dataSize);
00291                         readSize += (block.x1 * numberOfComponents * dataSize % 32);                    // add the bits left over from the beginning of the line
00292                         readSize = ((readSize + 31) / 32) * sizeof(U32);
00293 
00294                         // calculate buffer offset
00295                         int bufoff = line * dpxHeader.Width() * numberOfComponents;
00296         
00297                         fd->Read(dpxHeader, element, offset, readBuf, readSize);
00298 
00299                         // unpack the words in the buffer
00300                         int count = (block.x2 - block.x1 + 1) * numberOfComponents;
00301                         UnPackPacked<BUF, MASK, MULTIPLIER, REMAIN, REVERSE>(readBuf, dataSize, data, count, bufoff);
00302                 }
00303 
00304                 return true;
00305         }
00306         
00307         
00308         template <typename IR, typename BUF>
00309         bool Read10bitPacked(const Header &dpxHeader, U32 *readBuf, IR *fd, const int element, const Block &block, BUF *data)
00310         {
00311                 return ReadPacked<IR, BUF, MASK_10BITPACKED, MULTIPLIER_10BITPACKED, REMAIN_10BITPACKED, REVERSE_10BITPACKED>(dpxHeader, readBuf, fd, element, block, data);
00312                 
00313         }
00314         
00315         template <typename IR, typename BUF>
00316         bool Read12bitPacked(const Header &dpxHeader, U32 *readBuf, IR *fd, const int element, const Block &block, BUF *data)
00317         {
00318                 return ReadPacked<IR, BUF, MASK_12BITPACKED, MULTIPLIER_12BITPACKED, REMAIN_12BITPACKED, REVERSE_12BITPACKED>(dpxHeader, readBuf, fd, element, block, data);
00319         }
00320 
00321 
00322         template <typename IR, typename SRC, DataSize SRCTYPE, typename BUF, DataSize BUFTYPE>
00323         bool ReadBlockTypes(const Header &dpxHeader, SRC *readBuf, IR *fd, const int element, const Block &block, BUF *data)
00324         {
00325                 // get the number of components for this element descriptor
00326                 const int numberOfComponents = dpxHeader.ImageElementComponentCount(element);
00327                 
00328                 // byte count component type
00329                 const int bytes = dpxHeader.ComponentByteCount(element);
00330                         
00331                 // image image/height to read
00332                 const int width = (block.x2 - block.x1 + 1) * numberOfComponents;
00333                 const int height = block.y2 - block.y1 + 1;
00334                 
00335                 // end of line padding
00336                 int eolnPad = dpxHeader.EndOfLinePadding(element);
00337                 if (eolnPad == ~0)
00338                         eolnPad = 0;
00339 
00340                 // image width
00341                 const int imageWidth = dpxHeader.Width();
00342                 
00343                 // read in each line at a time directly into the user memory space
00344                 for (int line = 0; line < height; line++)
00345                 {
00346                         
00347                         // determine offset into image element
00348                         long offset = (line + block.y1) * imageWidth * numberOfComponents * bytes +
00349                                                 block.x1 * numberOfComponents * bytes + (line * eolnPad);
00350                                                 
00351                         if (BUFTYPE == SRCTYPE)
00352                         {
00353                                 fd->ReadDirect(dpxHeader, element, offset, reinterpret_cast<unsigned char *>(data + (width*line)), width*bytes);
00354                         }
00355                         else
00356                         {
00357                                 fd->Read(dpxHeader, element, offset, readBuf, width*bytes);
00358                                                         
00359                                 // convert data         
00360                                 for (int i = 0; i < width; i++)
00361                                         BaseTypeConverter(readBuf[i], data[width*line+i]);
00362                         }
00363         
00364                 }
00365 
00366                 return true;
00367         }
00368 
00369 
00370         template <typename IR, typename BUF>
00371         bool Read12bitFilledMethodB(const Header &dpxHeader, U16 *readBuf, IR *fd, const int element, const Block &block, BUF *data)
00372         {
00373                 // get the number of components for this element descriptor
00374                 const int numberOfComponents = dpxHeader.ImageElementComponentCount(element);
00375 
00376                 // image width & height to read
00377                 const int width = (block.x2 - block.x1 + 1) * numberOfComponents;
00378                 const int height = block.y2 - block.y1 + 1;
00379                 
00380                 // width of image
00381                 const int imageWidth = dpxHeader.Width();
00382         
00383                 // end of line padding (not a required data element so check for ~0)
00384                 int eolnPad = dpxHeader.EndOfLinePadding(element);
00385                 if (eolnPad == ~0)
00386                         eolnPad = 0;
00387                                 
00388                 // read in each line at a time directly into the user memory space
00389                 for (int line = 0; line < height; line++)
00390                 {
00391                         // determine offset into image element
00392                         long offset = (line + block.y1) * imageWidth * numberOfComponents * 2 +
00393                                                 block.x1 * numberOfComponents * 2 + (line * eolnPad);
00394         
00395                         fd->Read(dpxHeader, element, offset, readBuf, width*2);
00396                                 
00397                         // convert data         
00398                         for (int i = 0; i < width; i++)
00399                         {
00400                                 U16 d1 = readBuf[i];
00401                                 BaseTypeConvertU12ToU16(d1, d1);
00402                                 BaseTypeConverter(d1, data[width*line+i]);
00403                         }
00404                 }
00405 
00406                 return true;
00407         }
00408 
00409 #ifdef RLE_WORKING
00410         template <typename BUF, DataSize BUFTYPE>
00411         void ProcessImageBlock(const Header &dpxHeader,  const int element, U32 *readBuf, const int x, BUF *data, const int bufoff)
00412         {
00413                 const int bitDepth = dpxHeader.BitDepth(element);
00414                 const int numberOfComponents = dpxHeader.ImageElementComponentCount(element);
00415                 const Packing packing = dpxHeader.ImagePacking(element);
00416 
00417                 if (bitDepth == 10)
00418                 {       
00419                         if (packing == kFilledMethodA)
00420                                 Read10bitFilledMethodA<IR, BUF>(dpxHeader, readBuf, fd, element, block, reinterpret_cast<BUF *>(data));
00421                                 Unfill10bitFilled<BUF, PADDINGBITS_10BITFILLEDMETHODA>(readBuf, x, data, count, bufoff, numberOfComponents);
00422                         else if (packing == kFilledMethodB)
00423                                 Read10bitFilledMethodB<IR, BUF>(dpxHeader, readBuf, fd, element, block, reinterpret_cast<BUF *>(data));
00424                         else if (packing == kPacked)
00425                                 Read10bitPacked<IR, BUF>(dpxHeader, readBuf, fd, element, block, reinterpret_cast<BUF *>(data));
00426                                 UnPackPacked<BUF, MASK_10BITPACKED, MULTIPLIER_10BITPACKED, REMAIN_10BITPACKED, REVERSE_10BITPACKED>(readBuf, dataSize, data, count, bufoff);
00427                 } 
00428                 else if (bitDepth == 12)
00429                 {                       
00430                         if (packing == kPacked)
00431                                 Read12bitPacked<IR, BUF>(dpxHeader, readBuf, fd, element, block, reinterpret_cast<BUF *>(data));
00432                         else if (packing == kFilledMethodB)
00433                                 Read12bitFilledMethodB<IR, BUF>(dpxHeader, reinterpret_cast<U16 *>(readBuf), fd, element, block, reinterpret_cast<BUF *>(data));
00434                 }
00435         }
00436 #endif
00437         
00438         template <typename IR, typename BUF, DataSize BUFTYPE>
00439         bool ReadImageBlock(const Header &dpxHeader, U32 *readBuf, IR *fd, const int element, const Block &block, BUF *data)
00440         {
00441                 const int bitDepth = dpxHeader.BitDepth(element);
00442                 const DataSize size = dpxHeader.ComponentDataSize(element);     
00443                 const Packing packing = dpxHeader.ImagePacking(element);
00444                         
00445                 if (bitDepth == 10)
00446                 {       
00447                         if (packing == kFilledMethodA)
00448                                 return Read10bitFilledMethodA<IR, BUF>(dpxHeader, readBuf, fd, element, block, reinterpret_cast<BUF *>(data));  
00449                         else if (packing == kFilledMethodB)
00450                                 return Read10bitFilledMethodB<IR, BUF>(dpxHeader, readBuf, fd, element, block, reinterpret_cast<BUF *>(data));
00451                         else if (packing == kPacked)
00452                                 return Read10bitPacked<IR, BUF>(dpxHeader, readBuf, fd, element, block, reinterpret_cast<BUF *>(data));
00453                 } 
00454                 else if (bitDepth == 12)
00455                 {                       
00456                         if (packing == kPacked)
00457                                 return Read12bitPacked<IR, BUF>(dpxHeader, readBuf, fd, element, block, reinterpret_cast<BUF *>(data));
00458                         else if (packing == kFilledMethodB)
00459                                 // filled method B
00460                                 // 12 bits fill LSB of 16 bits
00461                                 return Read12bitFilledMethodB<IR, BUF>(dpxHeader, reinterpret_cast<U16 *>(readBuf), fd, element, block, reinterpret_cast<BUF *>(data));
00462                         else    
00463                                 // filled method A
00464                                 // 12 bits fill MSB of 16 bits
00465                                 return ReadBlockTypes<IR, U16, kWord, BUF, BUFTYPE>(dpxHeader, reinterpret_cast<U16 *>(readBuf), fd, element, block, reinterpret_cast<BUF *>(data));
00466                 }
00467                 else if (size == dpx::kByte)
00468                         return ReadBlockTypes<IR, U8, kByte, BUF, BUFTYPE>(dpxHeader, reinterpret_cast<U8 *>(readBuf), fd, element, block, reinterpret_cast<BUF *>(data));
00469                 else if (size == dpx::kWord)
00470                         return ReadBlockTypes<IR, U16, kWord, BUF, BUFTYPE>(dpxHeader, reinterpret_cast<U16 *>(readBuf), fd, element, block, reinterpret_cast<BUF *>(data));
00471                 else if (size == dpx::kInt)
00472                         return ReadBlockTypes<IR, U32, kInt, BUF, BUFTYPE>(dpxHeader, reinterpret_cast<U32 *>(readBuf), fd, element, block, reinterpret_cast<BUF *>(data));
00473                 else if (size == dpx::kFloat)
00474                         return ReadBlockTypes<IR, R32, kFloat, BUF, BUFTYPE>(dpxHeader, reinterpret_cast<R32 *>(readBuf), fd, element, block, reinterpret_cast<BUF *>(data));
00475                 else if (size == dpx::kDouble)
00476                         return ReadBlockTypes<IR, R64, kDouble, BUF, BUFTYPE>(dpxHeader, reinterpret_cast<R64 *>(readBuf), fd, element, block, reinterpret_cast<BUF *>(data));
00477 
00478                 // should not reach here
00479                 return false;
00480         }
00481 
00482         template <typename IR>
00483         bool ReadImageBlock(const Header &dpxHeader, U32 *readBuf, IR *fd, const int element, const Block &block, void *data, const DataSize size)
00484         {
00485                 if (size == dpx::kByte)
00486                         return ReadImageBlock<IR, U8, dpx::kByte>(dpxHeader, readBuf, fd, element, block, reinterpret_cast<U8 *>(data));
00487                 else if (size == dpx::kWord)
00488                         return ReadImageBlock<IR, U16, dpx::kWord>(dpxHeader, readBuf, fd, element, block, reinterpret_cast<U16 *>(data));
00489                 else if (size == dpx::kInt)
00490                         return ReadImageBlock<IR, U32, dpx::kInt>(dpxHeader, readBuf, fd, element, block, reinterpret_cast<U32 *>(data));
00491                 else if (size == dpx::kFloat)
00492                         return ReadImageBlock<IR, R32, dpx::kFloat>(dpxHeader, readBuf, fd, element, block, reinterpret_cast<R32 *>(data));     
00493                 else if (size == dpx::kDouble)
00494                         return ReadImageBlock<IR, R64, dpx::kDouble>(dpxHeader, readBuf, fd, element, block, reinterpret_cast<R64 *>(data));
00495 
00496                 // should not reach here
00497                 return false;
00498         }
00499 
00500 
00501 #ifdef RLE_WORKING
00502         // THIS IS PART OF THE INCOMPLETE RLE CODE
00503         
00504         // src is full image without any eoln padding
00505         template <typename SRC, typename DST>
00506         void CopyImageBlock(const Header &dpxHeader, const int element, SRC *src, DataSize srcSize, DST *dst, DataSize dstSize, const Block &block)
00507         {
00508                 const int numberOfComponents = dpxHeader.ImageElementComponentCount(element);
00509                 const int width = dpxHeader.Width();
00510                 const int byteCount = dpxHeader.ComponentByteCount(element);
00511                 const int pixelByteCount = numberOfComponents * byteCount;
00512 
00513                 int srcoff, dstoff;
00514                 int x, y, nc;
00515                 
00516                 if (srcSize == dstSize)
00517                 {
00518                         int lineSize = (width * numberOfComponents * byteCount);
00519                         U8 * srcU8 = reinterpret_cast<U8 *>(src);
00520                         U8 * dstU8 = reinterpret_cast<U8 *>(dst);
00521                         for (y = block.y1; y <= block.y2; y++)
00522                         {
00523                                 int copySize = (block.x2 - block.x1 + 1) * numberOfComponents * byteCount;
00524                                 memcpy(srcU8 + (y * lineSize) + (block.x1 * numberOfComponents * byteCount), dstU8, copySize);
00525                                 outBuf += copySize;
00526                         }
00527                         return;
00528                 }
00529                 
00530 
00531                 for (y = block.y1; y <= block.y2; y++)
00532                 {
00533                         dstoff = (y - block.y1) * ((block.x2 - block.x1 + 1) * numberOfComponents) - block.x1;
00534                         for (x = block.x1; x <= block.x2; x++)
00535                         {
00536                                 for (nc = 0; nc < numberOfComponents; nc++)
00537                                 {
00538                                         SRC d1 = src[(y * width * numberOfComponents) + (x * numberOfComponents) + nc];
00539                                         BaseTypeConverter(d1, dst[dstoff+((x-block.x1)*numberOfComponents) + nc]);
00540                                 }       
00541                         }
00542                 }
00543         }
00544         
00545         
00546         template<typename SRC>
00547         void CopyImageBlock(const Header &dpxHeader, const int element, SRC *src, DataSize srcSize, void *dst, DataSize dstSize, const Block &block)
00548         {
00549                 if (dstSize == dpx::kByte)
00550                         CopyImageBlock<SRC, U8>(dpxHeader, element, src, srcSize, reinterpret_cast<U8 *>(dst), dstSize, block);
00551                 else if (dstSize == dpx::kWord)
00552                         CopyImageBlock<SRC, U16>(dpxHeader, element, src, srcSize, reinterpret_cast<U16 *>(dst), dstSize, block);
00553                 else if (dstSize == dpx::kInt)
00554                         CopyImageBlock<SRC, U32>(dpxHeader, element, src, srcSize, reinterpret_cast<U32 *>(dst), dstSize, block);
00555                 else if (dstSize == dpx::kFloat)
00556                         CopyImageBlock<SRC, R32>(dpxHeader, element, src, srcSize, reinterpret_cast<R32 *>(dst), dstSize, block);
00557                 else if (dstSize == dpx::kDouble)
00558                         CopyImageBlock<SRC, R64>(dpxHeader, element, src, srcSize, reinterpret_cast<R64 *>(dst), dstSize, block);       
00559                 
00560         }
00561 
00562         
00563         void CopyImageBlock(const Header &dpxHeader, const int element, void *src, DataSize srcSize, void *dst, DataSize dstSize, const Block &block)
00564         {
00565                 if (srcSize == dpx::kByte)
00566                         CopyImageBlock<U8, dpx::kByte>(dpxHeader, element, reinterpret_cast<U8 *>(src), srcSize, dst, dstSize, block);
00567                 else if (srcSize == dpx::kWord)
00568                         CopyImageBlock<U16, dpx::kWord>(dpxHeader, element, reinterpret_cast<U16 *>(src), srcSize, dst, dstSize, block);
00569                 else if (srcSize == dpx::kInt)
00570                         CopyImageBlock<U32, dpx::kInt>(dpxHeader, element, reinterpret_cast<U32 *>(src), srcSize, dst, dstSize, block);
00571                 else if (srcSize == dpx::kFloat)
00572                         CopyImageBlock<R32, dpx::kFloat>(dpxHeader, element, reinterpret_cast<R32 *>(src), srcSize, dst, dstSize, block);
00573                 else if (srcSize == dpx::kDouble)
00574                         CopyImageBlock<R64, dpx::kDouble>(dpxHeader, element, reinterpret_cast<R64 *>(src), srcSize, dst, dstSize, block);      
00575                 
00576         }
00577 #endif
00578         
00579 }
00580 
00581 
00582 #endif
00583 
00584