TuttleOFX
1
|
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