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