1 // -*- mode: C++; tab-width: 4 -*- 2 // vi: ts=4 3 4 /* 5 * Copyright (c) 2009, Patrick A. Palmer. 6 * All rights reserved. 7 * 8 * Redistribution and use in source and binary forms, with or without 9 * modification, are permitted provided that the following conditions are met: 10 * 11 * - Redistributions of source code must retain the above copyright notice, 12 * this list of conditions and the following disclaimer. 13 * 14 * - Redistributions in binary form must reproduce the above copyright 15 * notice, this list of conditions and the following disclaimer in the 16 * documentation and/or other materials provided with the distribution. 17 * 18 * - Neither the name of Patrick A. Palmer nor the names of its 19 * contributors may be used to endorse or promote products derived from 20 * this software without specific prior written permission. 21 * 22 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 23 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 24 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 25 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 26 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 27 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 28 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 29 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 30 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 31 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 32 * POSSIBILITY OF SUCH DAMAGE. 33 */ 34 35 36 #ifndef _DPX_READERINTERNAL_H 37 #define _DPX_READERINTERNAL_H 1 38 39 40 #include <algorithm> 41 #include "BaseTypeConverter.h" 42 43 44 #define PADDINGBITS_10BITFILLEDMETHODA 2 45 #define PADDINGBITS_10BITFILLEDMETHODB 0 46 47 #define MASK_10BITPACKED 0xffc0 48 #define MULTIPLIER_10BITPACKED 2 49 #define REMAIN_10BITPACKED 4 50 #define REVERSE_10BITPACKED 6 51 52 #define MASK_12BITPACKED 0xfff0 53 #define MULTIPLIER_12BITPACKED 4 54 #define REMAIN_12BITPACKED 2 55 #define REVERSE_12BITPACKED 4 56 57 58 59 60 namespace dpx 61 { 62 63 // this function is called when the DataSize is 10 bit and the packing method is kFilledMethodA or kFilledMethodB 64 template<typename BUF, int PADDINGBITS> Unfill10bitFilled(U32 * readBuf,const int x,BUF * data,int count,int bufoff,const int numberOfComponents)65 void Unfill10bitFilled(U32 *readBuf, const int x, BUF *data, int count, int bufoff, const int numberOfComponents) 66 { 67 // unpack the words in the buffer 68 BUF *obuf = data + bufoff; 69 70 int index = (x * sizeof(U32)) % numberOfComponents; 71 72 for (int i = count - 1; i >= 0; i--) 73 { 74 // unpacking the buffer backwords 75 U32 word = readBuf[(i + index) / 3 / sizeof(U32)]; 76 U16 d1 = U16(word >> ((2 - (i + index) % 3) * 10 + PADDINGBITS) & 0x3ff); 77 BaseTypeConvertU10ToU16(d1, d1); 78 BaseTypeConverter(d1, obuf[i]); 79 } 80 #if 0 81 // NOTE: REVERSE -- is this something we really need to handle? 82 // There were many dpx images that write the components backwords 83 // because of some confusion with DPX v1 spec 84 85 switch (dpxHeader.DatumSwap(element)) 86 { 87 case 0: // no swap 88 for (i = count - 1; i >= 0; i--) 89 { 90 U32 word = readBuf[(i + index) / 3 / sizeof(U32)]; 91 U16 d1 = U16(word >> (((i + index) % 3) * 10 + PADDINGBITS) & 0x3ff); 92 BaseTypeConvertU10ToU16(d1, d1); 93 BaseTypeConverter(d1, obuf[i]); 94 } 95 96 case 1: // swap the three datum around so BGR becomes RGB 97 for (i = count - 1; i >= 0; i--) 98 { 99 // unpacking the buffer backwords 100 U32 word = readBuf[(i + index) / 3 / sizeof(U32)]; 101 U16 d1 = U16(word >> ((2 - (i + index) % 3) * 10 + PADDINGBITS) & 0x3ff); 102 BaseTypeConvertU10ToU16(d1, d1); 103 BaseTypeConverter(d1, obuf[i]); 104 } 105 106 // NOTE: NOT DONE case 2 107 case 2: // swap the second two of three datum around so YCrCb becomes YCbCr 108 for (i = count - 1; i >= 0; i--) 109 { 110 // unpacking the buffer backwords 111 U32 word = readBuf[(i + index) / 3 / sizeof(U32)]; 112 U16 d1 = U16(word >> ((2 - (count + index) % 3) * 10 + PADDINGBITS) & 0x3ff); 113 BaseTypeConvertU10ToU16(d1, d1); 114 BaseTypeConverter(d1, obuf[i]); 115 } 116 117 } 118 #endif 119 } 120 121 template <typename IR, typename BUF, int PADDINGBITS> Read10bitFilled(const Header & dpxHeader,U32 * readBuf,IR * fd,const int element,const Block & block,BUF * data)122 bool Read10bitFilled(const Header &dpxHeader, U32 *readBuf, IR *fd, const int element, const Block &block, BUF *data) 123 { 124 // image height to read 125 const int height = block.y2 - block.y1 + 1; 126 127 // get the number of components for this element descriptor 128 const int numberOfComponents = dpxHeader.ImageElementComponentCount(element); 129 130 // end of line padding 131 int eolnPad = dpxHeader.EndOfLinePadding(element); 132 133 // number of datums in one row 134 int datums = dpxHeader.Width() * numberOfComponents; 135 136 // Line length in bytes rounded to 32 bits boundary 137 int lineLength = ((datums - 1) / 3 + 1) * 4; 138 139 // read in each line at a time directly into the user memory space 140 for (int line = 0; line < height; line++) 141 { 142 // determine offset into image element 143 int actline = line + block.y1; 144 145 // first get line offset 146 long offset = actline * lineLength; 147 148 // add in eoln padding 149 offset += line * eolnPad; 150 151 // add in offset within the current line, rounding down so to catch any components within the word 152 offset += block.x1 * numberOfComponents / 3 * 4; 153 154 155 // get the read count in bytes, round to the 32-bit boundary 156 int readSize = (block.x2 - block.x1 + 1) * numberOfComponents; 157 readSize += readSize % 3; 158 readSize = readSize / 3 * 4; 159 160 // determine buffer offset 161 int bufoff = line * datums; 162 163 fd->Read(dpxHeader, element, offset, readBuf, readSize); 164 165 // unpack the words in the buffer 166 #if RLE_WORKING 167 int count = (block.x2 - block.x1 + 1) * numberOfComponents; 168 Unfill10bitFilled<BUF, PADDINGBITS>(readBuf, block.x1, data, count, bufoff, numberOfComponents); 169 #else 170 BUF *obuf = data + bufoff; 171 int index = (block.x1 * sizeof(U32)) % numberOfComponents; 172 173 for (int count = (block.x2 - block.x1 + 1) * numberOfComponents - 1; count >= 0; count--) 174 { 175 // unpacking the buffer backwords 176 U16 d1 = U16(readBuf[(count + index) / 3] >> ((2 - (count + index) % 3) * 10 + PADDINGBITS) & 0x3ff); 177 BaseTypeConvertU10ToU16(d1, d1); 178 179 BaseTypeConverter(d1, obuf[count]); 180 181 // work-around for 1-channel DPX images - to swap the outlying pixels, otherwise the columns are in the wrong order 182 if (numberOfComponents == 1 && count % 3 == 0) 183 std::swap(obuf[count], obuf[count + 2]); 184 } 185 #endif 186 } 187 188 return true; 189 } 190 191 192 template <typename IR, typename BUF> Read10bitFilledMethodA(const Header & dpx,U32 * readBuf,IR * fd,const int element,const Block & block,BUF * data)193 bool Read10bitFilledMethodA(const Header &dpx, U32 *readBuf, IR *fd, const int element, const Block &block, BUF *data) 194 { 195 // padding bits for PackedMethodA is 2 196 return Read10bitFilled<IR, BUF, PADDINGBITS_10BITFILLEDMETHODA>(dpx, readBuf, fd, element, block, data); 197 } 198 199 200 template <typename IR, typename BUF> Read10bitFilledMethodB(const Header & dpx,U32 * readBuf,IR * fd,const int element,const Block & block,BUF * data)201 bool Read10bitFilledMethodB(const Header &dpx, U32 *readBuf, IR *fd, const int element, const Block &block, BUF *data) 202 { 203 return Read10bitFilled<IR, BUF, PADDINGBITS_10BITFILLEDMETHODB>(dpx, readBuf, fd, element, block, data); 204 } 205 206 207 // 10 bit, packed data 208 // 12 bit, packed data 209 template <typename BUF, U32 MASK, int MULTIPLIER, int REMAIN, int REVERSE> UnPackPacked(U32 * readBuf,const int bitDepth,BUF * data,int count,int bufoff)210 void UnPackPacked(U32 *readBuf, const int bitDepth, BUF *data, int count, int bufoff) 211 { 212 // unpack the words in the buffer 213 BUF *obuf = data + bufoff; 214 215 for (int i = count - 1; i >= 0; i--) 216 { 217 // unpacking the buffer backwords 218 // find the byte that the data starts in, read in as a 16 bits then shift and mask 219 // the pattern with byte offset is: 220 // 10 bits datasize rotates every 4 data elements 221 // element 0 -> 6 bit shift to normalize at MSB (10 LSB shifted 6 bits) 222 // element 1 -> 4 bit shift to normalize at MSB 223 // element 2 -> 2 bit shift to normalize at MSB 224 // element 3 -> 0 bit shift to normalize at MSB 225 // 10 bit algorithm: (6-((count % 4)*2)) 226 // the pattern repeats every 160 bits 227 // 12 bits datasize rotates every 2 data elements 228 // element 0 -> 4 bit shift to normalize at MSB 229 // element 1 -> 0 bit shift to normalize at MSB 230 // 12 bit algorithm: (4-((count % 2)*4)) 231 // the pattern repeats every 96 bits 232 233 // first determine the word that the data element completely resides in 234 U16 *d1 = reinterpret_cast<U16 *>(reinterpret_cast<U8 *>(readBuf)+((i * bitDepth) / 8 /*bits*/)); 235 236 // place the component in the MSB and mask it for both 10-bit and 12-bit 237 U16 d2 = (*d1 << (REVERSE - ((i % REMAIN) * MULTIPLIER))) & MASK; 238 239 // For the 10/12 bit cases, specialize the 16-bit conversion by 240 // repacking into the LSB and using a specialized conversion 241 if(bitDepth == 10) 242 { 243 d2 = d2 >> REVERSE; 244 BaseTypeConvertU10ToU16(d2, d2); 245 } 246 else if(bitDepth == 12) 247 { 248 d2 = d2 >> REVERSE; 249 BaseTypeConvertU12ToU16(d2, d2); 250 } 251 252 BaseTypeConverter(d2, obuf[i]); 253 } 254 } 255 256 257 template <typename IR, typename BUF, U32 MASK, int MULTIPLIER, int REMAIN, int REVERSE> ReadPacked(const Header & dpxHeader,U32 * readBuf,IR * fd,const int element,const Block & block,BUF * data)258 bool ReadPacked(const Header &dpxHeader, U32 *readBuf, IR *fd, const int element, const Block &block, BUF *data) 259 { 260 // image height to read 261 const int height = block.y2 - block.y1 + 1; 262 263 // get the number of components for this element descriptor 264 const int numberOfComponents = dpxHeader.ImageElementComponentCount(element); 265 266 // end of line padding 267 int eolnPad = dpxHeader.EndOfLinePadding(element); 268 269 // data size in bits 270 const int dataSize = dpxHeader.BitDepth(element); 271 272 // number of bytes 273 const int lineSize = (dpxHeader.Width() * numberOfComponents * dataSize + 31) / 32; 274 275 // read in each line at a time directly into the user memory space 276 for (int line = 0; line < height; line++) 277 { 278 // determine offset into image element 279 long offset = (line + block.y1) * (lineSize * sizeof(U32)) + 280 (block.x1 * numberOfComponents * dataSize / 32 * sizeof(U32)) + (line * eolnPad); 281 282 // calculate read size 283 int readSize = ((block.x2 - block.x1 + 1) * numberOfComponents * dataSize); 284 readSize += (block.x1 * numberOfComponents * dataSize % 32); // add the bits left over from the beginning of the line 285 readSize = ((readSize + 31) / 32) * sizeof(U32); 286 287 // calculate buffer offset 288 int bufoff = line * dpxHeader.Width() * numberOfComponents; 289 290 fd->Read(dpxHeader, element, offset, readBuf, readSize); 291 292 // unpack the words in the buffer 293 int count = (block.x2 - block.x1 + 1) * numberOfComponents; 294 UnPackPacked<BUF, MASK, MULTIPLIER, REMAIN, REVERSE>(readBuf, dataSize, data, count, bufoff); 295 } 296 297 return true; 298 } 299 300 301 template <typename IR, typename BUF> Read10bitPacked(const Header & dpxHeader,U32 * readBuf,IR * fd,const int element,const Block & block,BUF * data)302 bool Read10bitPacked(const Header &dpxHeader, U32 *readBuf, IR *fd, const int element, const Block &block, BUF *data) 303 { 304 return ReadPacked<IR, BUF, MASK_10BITPACKED, MULTIPLIER_10BITPACKED, REMAIN_10BITPACKED, REVERSE_10BITPACKED>(dpxHeader, readBuf, fd, element, block, data); 305 306 } 307 308 template <typename IR, typename BUF> Read12bitPacked(const Header & dpxHeader,U32 * readBuf,IR * fd,const int element,const Block & block,BUF * data)309 bool Read12bitPacked(const Header &dpxHeader, U32 *readBuf, IR *fd, const int element, const Block &block, BUF *data) 310 { 311 return ReadPacked<IR, BUF, MASK_12BITPACKED, MULTIPLIER_12BITPACKED, REMAIN_12BITPACKED, REVERSE_12BITPACKED>(dpxHeader, readBuf, fd, element, block, data); 312 } 313 314 315 template <typename IR, typename SRC, DataSize SRCTYPE, typename BUF, DataSize BUFTYPE> ReadBlockTypes(const Header & dpxHeader,SRC * readBuf,IR * fd,const int element,const Block & block,BUF * data)316 bool ReadBlockTypes(const Header &dpxHeader, SRC *readBuf, IR *fd, const int element, const Block &block, BUF *data) 317 { 318 // get the number of components for this element descriptor 319 const int numberOfComponents = dpxHeader.ImageElementComponentCount(element); 320 321 // byte count component type 322 const int bytes = dpxHeader.ComponentByteCount(element); 323 324 // image image/height to read 325 const int width = (block.x2 - block.x1 + 1) * numberOfComponents; 326 const int height = block.y2 - block.y1 + 1; 327 328 // end of line padding 329 int eolnPad = dpxHeader.EndOfLinePadding(element); 330 if (eolnPad == ~0) 331 eolnPad = 0; 332 333 // image width 334 const int imageWidth = dpxHeader.Width(); 335 336 // read in each line at a time directly into the user memory space 337 for (int line = 0; line < height; line++) 338 { 339 340 // determine offset into image element 341 long offset = (line + block.y1) * imageWidth * numberOfComponents * bytes + 342 block.x1 * numberOfComponents * bytes + (line * eolnPad); 343 344 if (BUFTYPE == SRCTYPE) 345 { 346 fd->ReadDirect(dpxHeader, element, offset, reinterpret_cast<unsigned char *>(data + (width*line)), width*bytes); 347 } 348 else 349 { 350 fd->Read(dpxHeader, element, offset, readBuf, width*bytes); 351 352 // convert data 353 for (int i = 0; i < width; i++) 354 BaseTypeConverter(readBuf[i], data[width*line+i]); 355 } 356 357 } 358 359 return true; 360 } 361 362 363 template <typename IR, typename BUF> Read12bitFilledMethodB(const Header & dpxHeader,U16 * readBuf,IR * fd,const int element,const Block & block,BUF * data)364 bool Read12bitFilledMethodB(const Header &dpxHeader, U16 *readBuf, IR *fd, const int element, const Block &block, BUF *data) 365 { 366 // get the number of components for this element descriptor 367 const int numberOfComponents = dpxHeader.ImageElementComponentCount(element); 368 369 // image width & height to read 370 const int width = (block.x2 - block.x1 + 1) * numberOfComponents; 371 const int height = block.y2 - block.y1 + 1; 372 373 // width of image 374 const int imageWidth = dpxHeader.Width(); 375 376 // end of line padding (not a required data element so check for ~0) 377 int eolnPad = dpxHeader.EndOfLinePadding(element); 378 if (eolnPad == ~0) 379 eolnPad = 0; 380 381 // read in each line at a time directly into the user memory space 382 for (int line = 0; line < height; line++) 383 { 384 // determine offset into image element 385 long offset = (line + block.y1) * imageWidth * numberOfComponents * 2 + 386 block.x1 * numberOfComponents * 2 + (line * eolnPad); 387 388 fd->Read(dpxHeader, element, offset, readBuf, width*2); 389 390 // convert data 391 for (int i = 0; i < width; i++) 392 { 393 U16 d1 = readBuf[i]; 394 BaseTypeConvertU12ToU16(d1, d1); 395 BaseTypeConverter(d1, data[width*line+i]); 396 } 397 } 398 399 return true; 400 } 401 402 #ifdef RLE_WORKING 403 template <typename BUF, DataSize BUFTYPE> ProcessImageBlock(const Header & dpxHeader,const int element,U32 * readBuf,const int x,BUF * data,const int bufoff)404 void ProcessImageBlock(const Header &dpxHeader, const int element, U32 *readBuf, const int x, BUF *data, const int bufoff) 405 { 406 const int bitDepth = dpxHeader.BitDepth(element); 407 const int numberOfComponents = dpxHeader.ImageElementComponentCount(element); 408 const Packing packing = dpxHeader.ImagePacking(element); 409 410 if (bitDepth == 10) 411 { 412 if (packing == kFilledMethodA) 413 Read10bitFilledMethodA<IR, BUF>(dpxHeader, readBuf, fd, element, block, reinterpret_cast<BUF *>(data)); 414 Unfill10bitFilled<BUF, PADDINGBITS_10BITFILLEDMETHODA>(readBuf, x, data, count, bufoff, numberOfComponents); 415 else if (packing == kFilledMethodB) 416 Read10bitFilledMethodB<IR, BUF>(dpxHeader, readBuf, fd, element, block, reinterpret_cast<BUF *>(data)); 417 else if (packing == kPacked) 418 Read10bitPacked<IR, BUF>(dpxHeader, readBuf, fd, element, block, reinterpret_cast<BUF *>(data)); 419 UnPackPacked<BUF, MASK_10BITPACKED, MULTIPLIER_10BITPACKED, REMAIN_10BITPACKED, REVERSE_10BITPACKED>(readBuf, dataSize, data, count, bufoff); 420 } 421 else if (bitDepth == 12) 422 { 423 if (packing == kPacked) 424 Read12bitPacked<IR, BUF>(dpxHeader, readBuf, fd, element, block, reinterpret_cast<BUF *>(data)); 425 else if (packing == kFilledMethodB) 426 Read12bitFilledMethodB<IR, BUF>(dpxHeader, reinterpret_cast<U16 *>(readBuf), fd, element, block, reinterpret_cast<BUF *>(data)); 427 } 428 } 429 #endif 430 431 template <typename IR, typename BUF, DataSize BUFTYPE> ReadImageBlock(const Header & dpxHeader,U32 * readBuf,IR * fd,const int element,const Block & block,BUF * data)432 bool ReadImageBlock(const Header &dpxHeader, U32 *readBuf, IR *fd, const int element, const Block &block, BUF *data) 433 { 434 const int bitDepth = dpxHeader.BitDepth(element); 435 const DataSize size = dpxHeader.ComponentDataSize(element); 436 const Packing packing = dpxHeader.ImagePacking(element); 437 438 if (bitDepth == 10) 439 { 440 if (packing == kFilledMethodA) 441 return Read10bitFilledMethodA<IR, BUF>(dpxHeader, readBuf, fd, element, block, reinterpret_cast<BUF *>(data)); 442 else if (packing == kFilledMethodB) 443 return Read10bitFilledMethodB<IR, BUF>(dpxHeader, readBuf, fd, element, block, reinterpret_cast<BUF *>(data)); 444 else if (packing == kPacked) 445 return Read10bitPacked<IR, BUF>(dpxHeader, readBuf, fd, element, block, reinterpret_cast<BUF *>(data)); 446 } 447 else if (bitDepth == 12) 448 { 449 if (packing == kPacked) 450 return Read12bitPacked<IR, BUF>(dpxHeader, readBuf, fd, element, block, reinterpret_cast<BUF *>(data)); 451 else if (packing == kFilledMethodB) 452 // filled method B 453 // 12 bits fill LSB of 16 bits 454 return Read12bitFilledMethodB<IR, BUF>(dpxHeader, reinterpret_cast<U16 *>(readBuf), fd, element, block, reinterpret_cast<BUF *>(data)); 455 else 456 // filled method A 457 // 12 bits fill MSB of 16 bits 458 return ReadBlockTypes<IR, U16, kWord, BUF, BUFTYPE>(dpxHeader, reinterpret_cast<U16 *>(readBuf), fd, element, block, reinterpret_cast<BUF *>(data)); 459 } 460 else if (size == dpx::kByte) 461 return ReadBlockTypes<IR, U8, kByte, BUF, BUFTYPE>(dpxHeader, reinterpret_cast<U8 *>(readBuf), fd, element, block, reinterpret_cast<BUF *>(data)); 462 else if (size == dpx::kWord) 463 return ReadBlockTypes<IR, U16, kWord, BUF, BUFTYPE>(dpxHeader, reinterpret_cast<U16 *>(readBuf), fd, element, block, reinterpret_cast<BUF *>(data)); 464 else if (size == dpx::kInt) 465 return ReadBlockTypes<IR, U32, kInt, BUF, BUFTYPE>(dpxHeader, reinterpret_cast<U32 *>(readBuf), fd, element, block, reinterpret_cast<BUF *>(data)); 466 else if (size == dpx::kFloat) 467 return ReadBlockTypes<IR, R32, kFloat, BUF, BUFTYPE>(dpxHeader, reinterpret_cast<R32 *>(readBuf), fd, element, block, reinterpret_cast<BUF *>(data)); 468 else if (size == dpx::kDouble) 469 return ReadBlockTypes<IR, R64, kDouble, BUF, BUFTYPE>(dpxHeader, reinterpret_cast<R64 *>(readBuf), fd, element, block, reinterpret_cast<BUF *>(data)); 470 471 // should not reach here 472 return false; 473 } 474 475 template <typename IR> ReadImageBlock(const Header & dpxHeader,U32 * readBuf,IR * fd,const int element,const Block & block,void * data,const DataSize size)476 bool ReadImageBlock(const Header &dpxHeader, U32 *readBuf, IR *fd, const int element, const Block &block, void *data, const DataSize size) 477 { 478 if (size == dpx::kByte) 479 return ReadImageBlock<IR, U8, dpx::kByte>(dpxHeader, readBuf, fd, element, block, reinterpret_cast<U8 *>(data)); 480 else if (size == dpx::kWord) 481 return ReadImageBlock<IR, U16, dpx::kWord>(dpxHeader, readBuf, fd, element, block, reinterpret_cast<U16 *>(data)); 482 else if (size == dpx::kInt) 483 return ReadImageBlock<IR, U32, dpx::kInt>(dpxHeader, readBuf, fd, element, block, reinterpret_cast<U32 *>(data)); 484 else if (size == dpx::kFloat) 485 return ReadImageBlock<IR, R32, dpx::kFloat>(dpxHeader, readBuf, fd, element, block, reinterpret_cast<R32 *>(data)); 486 else if (size == dpx::kDouble) 487 return ReadImageBlock<IR, R64, dpx::kDouble>(dpxHeader, readBuf, fd, element, block, reinterpret_cast<R64 *>(data)); 488 489 // should not reach here 490 return false; 491 } 492 493 494 #ifdef RLE_WORKING 495 // THIS IS PART OF THE INCOMPLETE RLE CODE 496 497 // src is full image without any eoln padding 498 template <typename SRC, typename DST> CopyImageBlock(const Header & dpxHeader,const int element,SRC * src,DataSize srcSize,DST * dst,DataSize dstSize,const Block & block)499 void CopyImageBlock(const Header &dpxHeader, const int element, SRC *src, DataSize srcSize, DST *dst, DataSize dstSize, const Block &block) 500 { 501 const int numberOfComponents = dpxHeader.ImageElementComponentCount(element); 502 const int width = dpxHeader.Width(); 503 const int byteCount = dpxHeader.ComponentByteCount(element); 504 const int pixelByteCount = numberOfComponents * byteCount; 505 506 int srcoff, dstoff; 507 int x, y, nc; 508 509 if (srcSize == dstSize) 510 { 511 int lineSize = (width * numberOfComponents * byteCount); 512 U8 * srcU8 = reinterpret_cast<U8 *>(src); 513 U8 * dstU8 = reinterpret_cast<U8 *>(dst); 514 for (y = block.y1; y <= block.y2; y++) 515 { 516 int copySize = (block.x2 - block.x1 + 1) * numberOfComponents * byteCount; 517 memcpy(srcU8 + (y * lineSize) + (block.x1 * numberOfComponents * byteCount), dstU8, copySize); 518 outBuf += copySize; 519 } 520 return; 521 } 522 523 524 for (y = block.y1; y <= block.y2; y++) 525 { 526 dstoff = (y - block.y1) * ((block.x2 - block.x1 + 1) * numberOfComponents) - block.x1; 527 for (x = block.x1; x <= block.x2; x++) 528 { 529 for (nc = 0; nc < numberOfComponents; nc++) 530 { 531 SRC d1 = src[(y * width * numberOfComponents) + (x * numberOfComponents) + nc]; 532 BaseTypeConverter(d1, dst[dstoff+((x-block.x1)*numberOfComponents) + nc]); 533 } 534 } 535 } 536 } 537 538 539 template<typename SRC> CopyImageBlock(const Header & dpxHeader,const int element,SRC * src,DataSize srcSize,void * dst,DataSize dstSize,const Block & block)540 void CopyImageBlock(const Header &dpxHeader, const int element, SRC *src, DataSize srcSize, void *dst, DataSize dstSize, const Block &block) 541 { 542 if (dstSize == dpx::kByte) 543 CopyImageBlock<SRC, U8>(dpxHeader, element, src, srcSize, reinterpret_cast<U8 *>(dst), dstSize, block); 544 else if (dstSize == dpx::kWord) 545 CopyImageBlock<SRC, U16>(dpxHeader, element, src, srcSize, reinterpret_cast<U16 *>(dst), dstSize, block); 546 else if (dstSize == dpx::kInt) 547 CopyImageBlock<SRC, U32>(dpxHeader, element, src, srcSize, reinterpret_cast<U32 *>(dst), dstSize, block); 548 else if (dstSize == dpx::kFloat) 549 CopyImageBlock<SRC, R32>(dpxHeader, element, src, srcSize, reinterpret_cast<R32 *>(dst), dstSize, block); 550 else if (dstSize == dpx::kDouble) 551 CopyImageBlock<SRC, R64>(dpxHeader, element, src, srcSize, reinterpret_cast<R64 *>(dst), dstSize, block); 552 553 } 554 555 CopyImageBlock(const Header & dpxHeader,const int element,void * src,DataSize srcSize,void * dst,DataSize dstSize,const Block & block)556 void CopyImageBlock(const Header &dpxHeader, const int element, void *src, DataSize srcSize, void *dst, DataSize dstSize, const Block &block) 557 { 558 if (srcSize == dpx::kByte) 559 CopyImageBlock<U8, dpx::kByte>(dpxHeader, element, reinterpret_cast<U8 *>(src), srcSize, dst, dstSize, block); 560 else if (srcSize == dpx::kWord) 561 CopyImageBlock<U16, dpx::kWord>(dpxHeader, element, reinterpret_cast<U16 *>(src), srcSize, dst, dstSize, block); 562 else if (srcSize == dpx::kInt) 563 CopyImageBlock<U32, dpx::kInt>(dpxHeader, element, reinterpret_cast<U32 *>(src), srcSize, dst, dstSize, block); 564 else if (srcSize == dpx::kFloat) 565 CopyImageBlock<R32, dpx::kFloat>(dpxHeader, element, reinterpret_cast<R32 *>(src), srcSize, dst, dstSize, block); 566 else if (srcSize == dpx::kDouble) 567 CopyImageBlock<R64, dpx::kDouble>(dpxHeader, element, reinterpret_cast<R64 *>(src), srcSize, dst, dstSize, block); 568 569 } 570 #endif 571 572 } 573 574 575 #endif 576 577 578