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 #include "DPX.h" 00036 #include "RunLengthEncoding.h" 00037 #include "ElementReadStream.h" 00038 #include "ReaderInternal.h" 00039 00040 00041 00042 // Basic size of a packet is the number of bytes that all data packing methods will fit into that are whole and complete 00043 #define PACKET_REPEAT (10 * sizeof(U32)) // 320 bits repeating pattern 00044 #define BUFFER_SIZE (PACKET_REPEAT * 1002) // read in temp buffer size 00045 #define EXPANDED_BUFFER_SIZE (BUFFER_SIZE + (BUFFER_SIZE / 3)) // expaded size after unpacking (max) 00046 00047 00048 dpx::RunLengthEncoding::RunLengthEncoding() : buf(0) 00049 { 00050 } 00051 00052 00053 dpx::RunLengthEncoding::~RunLengthEncoding() 00054 { 00055 if (this->buf) 00056 delete [] buf; 00057 } 00058 00059 00060 void dpx::RunLengthEncoding::Reset() 00061 { 00062 if (this->buf) 00063 { 00064 delete [] buf; 00065 this->buf = 0; 00066 } 00067 } 00068 00069 00070 bool dpx::RunLengthEncoding::Read(const Header &dpxHeader, ElementReadStream *fd, const int element, const Block &block, void *data, const DataSize size) 00071 { 00072 int i; 00073 00074 // just check to make sure that this element is RLE 00075 if (dpxHeader.ImageEncoding(element) != kRLE) 00076 return false; 00077 00078 00079 // get the number of components for this element descriptor 00080 const int numberOfComponents = dpxHeader.ImageElementComponentCount(element); 00081 const int width = dpxHeader.Width(); 00082 const int height = dpxHeader.Height(); 00083 const int byteCount = dpxHeader.ComponentByteCount(element); 00084 const U32 eolnPad = dpxHeader.EndOfLinePadding(element); 00085 //DataSize srcSize = dpxHeader.ComponentDataSize(element); 00086 00087 // has the buffer been read in and decoded? 00088 if (this->buf == 0) 00089 { 00090 // not yet 00091 00092 // bit depth of the image element 00093 const int bitDepth = dpxHeader.BitDepth(element); 00094 00095 // error out if the bit depth 10 or 12 and have eoln bytes 00096 // this is particularly slow to parse and eoln padding bytes 00097 // are not needed for those formats 00098 // also if end of padding makes the line length odd, error out for that as well 00099 if (bitDepth != 8 && bitDepth != 16 && eolnPad > 0) 00100 return false; 00101 else if (bitDepth == 16 && eolnPad != 2 && eolnPad != 0) 00102 return false; 00103 00104 // error out for real types since bit operations don't really make sense 00105 if (size == kFloat || size == kDouble) 00106 return false; 00107 00108 // find start and possible end of the element 00109 U32 startOffset = dpxHeader.DataOffset(element); 00110 U32 endOffset = 0xffffffff; 00111 U32 currentOffset = startOffset; 00112 00113 for (i = 0; i < MAX_ELEMENTS; i++) 00114 { 00115 if (i == element) 00116 continue; 00117 U32 doff = dpxHeader.DataOffset(i); 00118 if (doff == 0xffffffff) 00119 continue; 00120 if (doff > startOffset && (endOffset == 0xffffffff || doff < endOffset)) 00121 endOffset = doff - 1; 00122 } 00123 00124 00125 // size of the image 00126 const size_t imageSize = width * height * numberOfComponents; 00127 const size_t imageByteSize = imageSize * byteCount; 00128 00129 // allocate the buffer that will store the entire image 00130 this->buf = new U8[imageByteSize]; 00131 00132 // allocate the temporary buffer that will read in the encoded image 00133 U8 *tempBuf = new U8[EXPANDED_BUFFER_SIZE]; 00134 00135 // xpos, ypos in decoding 00136 /*int xpos = 0; 00137 int ypos = 0;*/ 00138 00139 // read in the encoded image block at a time 00140 bool done = false; 00141 while (!done) 00142 { 00143 // read in temp buffer 00144 size_t rs = fd->ReadDirect(dpxHeader, element, (currentOffset - startOffset), tempBuf, BUFFER_SIZE); 00145 currentOffset += rs; 00146 if (rs != BUFFER_SIZE) 00147 done = true; 00148 else if (endOffset != 0xffffffff && currentOffset >= endOffset) 00149 done = true; 00150 00151 // if 10-bit, 12-bit, unpack or unfill 00152 00153 // step through and decode 00154 00155 00156 } 00157 00158 // no longer need temp buffer 00159 delete [] tempBuf; 00160 } 00161 00162 00163 #ifdef RLE_WORKING 00164 // NOT COMPLETE YET 00165 // copy buffer 00166 CopyImageBlock(dpxHeader, element, buf, srcSize, data, size, dstSize, block); 00167 #endif 00168 return true; 00169 } 00170 00171