1 ///////////////////////////////////////////////////////////////////////////
2 //
3 // Copyright (c) 2011, Industrial Light & Magic, a division of Lucas
4 // Digital Ltd. LLC
5 //
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
10 // met:
11 // *       Redistributions of source code must retain the above copyright
12 // notice, this list of conditions and the following disclaimer.
13 // *       Redistributions in binary form must reproduce the above
14 // copyright notice, this list of conditions and the following disclaimer
15 // in the documentation and/or other materials provided with the
16 // distribution.
17 // *       Neither the name of Industrial Light & Magic nor the names of
18 // its contributors may be used to endorse or promote products derived
19 // from this software without specific prior written permission.
20 //
21 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
24 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
25 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
26 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
27 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
28 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
29 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
31 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32 //
33 ///////////////////////////////////////////////////////////////////////////
34 
35 
36 #ifndef INCLUDED_IMF_DEEP_SCAN_LINE_INPUT_FILE_H
37 #define INCLUDED_IMF_DEEP_SCAN_LINE_INPUT_FILE_H
38 
39 //-----------------------------------------------------------------------------
40 //
41 //      class DeepScanLineInputFile
42 //
43 //-----------------------------------------------------------------------------
44 
45 #include "ImfThreading.h"
46 #include "ImfGenericInputFile.h"
47 #include "ImfNamespace.h"
48 #include "ImfForward.h"
49 #include "ImfExport.h"
50 #include "ImfDeepScanLineOutputFile.h"
51 
52 OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_ENTER
53 
54 
55 class IMF_EXPORT DeepScanLineInputFile : public GenericInputFile
56 {
57   public:
58 
59     //------------
60     // Constructor
61     //------------
62 
63     DeepScanLineInputFile (const char fileName[],
64                            int numThreads = globalThreadCount());
65 
66     DeepScanLineInputFile (const Header &header, OPENEXR_IMF_INTERNAL_NAMESPACE::IStream *is,
67                            int version, /*version field from file*/
68                            int numThreads = globalThreadCount());
69 
70 
71     //-----------------------------------------
72     // Destructor -- deallocates internal data
73     // structures, but does not close the file.
74     //-----------------------------------------
75 
76     virtual ~DeepScanLineInputFile ();
77 
78 
79     //------------------------
80     // Access to the file name
81     //------------------------
82 
83     const char *        fileName () const;
84 
85 
86     //--------------------------
87     // Access to the file header
88     //--------------------------
89 
90     const Header &      header () const;
91 
92 
93     //----------------------------------
94     // Access to the file format version
95     //----------------------------------
96 
97     int                 version () const;
98 
99 
100     //-----------------------------------------------------------
101     // Set the current frame buffer -- copies the FrameBuffer
102     // object into the InputFile object.
103     //
104     // The current frame buffer is the destination for the pixel
105     // data read from the file.  The current frame buffer must be
106     // set at least once before readPixels() is called.
107     // The current frame buffer can be changed after each call
108     // to readPixels().
109     //-----------------------------------------------------------
110 
111     void                setFrameBuffer (const DeepFrameBuffer &frameBuffer);
112 
113 
114     //-----------------------------------
115     // Access to the current frame buffer
116     //-----------------------------------
117 
118     const DeepFrameBuffer & frameBuffer () const;
119 
120 
121     //---------------------------------------------------------------
122     // Check if the file is complete:
123     //
124     // isComplete() returns true if all pixels in the data window are
125     // present in the input file, or false if any pixels are missing.
126     // (Another program may still be busy writing the file, or file
127     // writing may have been aborted prematurely.)
128     //---------------------------------------------------------------
129 
130     bool                isComplete () const;
131 
132 
133     //---------------------------------------------------------------
134     // Read pixel data:
135     //
136     // readPixels(s1,s2) reads all scan lines with y coordinates
137     // in the interval [min (s1, s2), max (s1, s2)] from the file,
138     // and stores them in the current frame buffer.
139     //
140     // Both s1 and s2 must be within the interval
141     // [header().dataWindow().min.y, header.dataWindow().max.y]
142     //
143     // The scan lines can be read from the file in random order, and
144     // individual scan lines may be skipped or read multiple times.
145     // For maximum efficiency, the scan lines should be read in the
146     // order in which they were written to the file.
147     //
148     // readPixels(s) calls readPixels(s,s).
149     //
150     // If threading is enabled, readPixels (s1, s2) tries to perform
151     // decopmression of multiple scanlines in parallel.
152     //
153     //---------------------------------------------------------------
154 
155     void                readPixels (int scanLine1, int scanLine2);
156     void                readPixels (int scanLine);
157 
158 
159 
160     //---------------------------------------------------------------
161     // Extract pixel data from pre-read block
162     //
163     // readPixels(rawPixelData,frameBuffer,s1,s2) reads all scan lines with y coordinates
164     // in the interval [min (s1, s2), max (s1, s2)] from the data provided and
165     // stores them in the provided frameBuffer.
166     // the data can be obtained from a call to rawPixelData()
167     //
168     //
169     // Both s1 and s2 must be within the data specified
170     //
171     // you must provide a frameBuffer with a samplecountslice, which must have been read
172     // and the data valid - readPixels uses your sample count buffer to compute
173     // offsets to the data it needs
174     //
175     // This call does not block, and is thread safe for clients with an existing
176     // threading model. The InputFile's frameBuffer is not used in this call.
177     //
178     // This call is only provided for clients which have an existing threading model in place
179     // and unpredictable access patterns to the data.
180     // The fastest way to read an entire image is to enable threading,use setFrameBuffer then
181     // readPixels(header().dataWindow().min.y, header.dataWindow().max.y)
182     //
183     //---------------------------------------------------------------
184 
185     void                readPixels (const char * rawPixelData,
186                                     const DeepFrameBuffer & frameBuffer,
187                                     int scanLine1,
188                                     int scanLine2) const;
189 
190     //----------------------------------------------
191     // Read a block of raw pixel data from the file,
192     // without uncompressing it (this function is
193     // used to implement OutputFile::copyPixels()).
194     // note: returns the entire payload of the relevant chunk of data, not including part number
195     // including compressed and uncompressed sizes
196     // on entry, if pixelDataSize is insufficiently large, no bytes are read (pixelData can safely be NULL)
197     // on exit, pixelDataSize is the number of bytes required to read the chunk
198     //
199     //----------------------------------------------
200 
201     void                rawPixelData (int firstScanLine,
202                                       char * pixelData,
203                                       Int64 &pixelDataSize);
204 
205 
206     //-------------------------------------------------
207     // firstScanLineInChunk() returns the row number of the first row that's stored in the
208     // same chunk as scanline y. Depending on the compression mode, this may not be the same as y
209     //
210     // lastScanLineInChunk() returns the row number of the last row that's stored in the same
211     // chunk as scanline y.  Depending on the compression mode, this may not be the same as y.
212     // The last chunk in the file may be smaller than all the others
213     //
214     //------------------------------------------------
215     int                 firstScanLineInChunk(int y) const;
216     int                 lastScanLineInChunk (int y) const;
217 
218     //-----------------------------------------------------------
219     // Read pixel sample counts into a slice in the frame buffer.
220     //
221     // readPixelSampleCounts(s1, s2) reads all the counts of
222     // pixel samples with y coordinates in the interval
223     // [min (s1, s2), max (s1, s2)] from the file, and stores
224     // them in the slice naming "sample count".
225     //
226     // Both s1 and s2 must be within the interval
227     // [header().dataWindow().min.y, header.dataWindow().max.y]
228     //
229     // readPixelSampleCounts(s) calls readPixelSampleCounts(s,s).
230     //
231     //-----------------------------------------------------------
232 
233     void                readPixelSampleCounts (int scanline1,
234                                                int scanline2);
235     void                readPixelSampleCounts (int scanline);
236 
237 
238     //----------------------------------------------------------
239     // Read pixel sample counts into the provided frameBuffer
240     // using a block read of data read by rawPixelData
241     // for multi-scanline compression schemes, you must decode the entire block
242     // so scanline1=firstScanLineInChunk(y) and scanline2=lastScanLineInChunk(y)
243     //
244     // This call does not block, and is thread safe for clients with an existing
245     // threading model. The InputFile's frameBuffer is not used in this call.
246     //
247     // The fastest way to read an entire image is to enable threading in OpenEXR, use setFrameBuffer then
248     // readPixelSampleCounts(header().dataWindow().min.y, header.dataWindow().max.y)
249     //
250     //----------------------------------------------------------
251     void                readPixelSampleCounts (const char * rawdata ,
252                                                const DeepFrameBuffer & frameBuffer,
253                                                int scanLine1 ,
254                                                int scanLine2) const;
255 
256     struct Data;
257 
258   private:
259 
260     Data *              _data;
261 
262     DeepScanLineInputFile   (InputPartData* part);
263 
264     void                initialize(const Header& header);
265     void compatibilityInitialize(OPENEXR_IMF_INTERNAL_NAMESPACE::IStream & is);
266     void multiPartInitialize(InputPartData* part);
267 
268     friend class         InputFile;
269     friend class MultiPartInputFile;
270     friend void DeepScanLineOutputFile::copyPixels(DeepScanLineInputFile &);
271 };
272 
273 
274 OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_EXIT
275 
276 #endif
277