1 /*
2 Copyright (c) 2003-2010 Sony Pictures Imageworks Inc., et al.
3 All Rights Reserved.
4 
5 Redistribution and use in source and binary forms, with or without
6 modification, are permitted provided that the following conditions are
7 met:
8 * Redistributions of source code must retain the above copyright
9   notice, this list of conditions and the following disclaimer.
10 * Redistributions in binary form must reproduce the above copyright
11   notice, this list of conditions and the following disclaimer in the
12   documentation and/or other materials provided with the distribution.
13 * Neither the name of Sony Pictures Imageworks nor the names of its
14   contributors may be used to endorse or promote products derived from
15   this software without specific prior written permission.
16 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17 "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19 A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20 OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21 SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22 LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28 
29 #include <OpenColorIO/OpenColorIO.h>
30 
31 #include "FileTransform.h"
32 #include "MatrixOps.h"
33 #include "ParseUtils.h"
34 #include "pystring/pystring.h"
35 
36 #include <cstdio>
37 #include <cstring>
38 #include <sstream>
39 
40 
41 OCIO_NAMESPACE_ENTER
42 {
43     ////////////////////////////////////////////////////////////////
44 
45     namespace
46     {
47         class LocalCachedFile : public CachedFile
48         {
49         public:
50             LocalCachedFile()
51             {
52                 memset(m44, 0, 16*sizeof(float));
53                 memset(offset4, 0, 4*sizeof(float));
54             };
55             ~LocalCachedFile() {};
56 
57             float m44[16];
58             float offset4[4];
59         };
60 
61         typedef OCIO_SHARED_PTR<LocalCachedFile> LocalCachedFileRcPtr;
62 
63 
64 
65         class LocalFileFormat : public FileFormat
66         {
67         public:
68 
69             ~LocalFileFormat() {};
70 
71             virtual void GetFormatInfo(FormatInfoVec & formatInfoVec) const;
72 
73             virtual CachedFileRcPtr Read(std::istream & istream) const;
74 
75             virtual void BuildFileOps(OpRcPtrVec & ops,
76                          const Config& config,
77                          const ConstContextRcPtr & context,
78                          CachedFileRcPtr untypedCachedFile,
79                          const FileTransform& fileTransform,
80                          TransformDirection dir) const;
81         };
82 
83         void LocalFileFormat::GetFormatInfo(FormatInfoVec & formatInfoVec) const
84         {
85             FormatInfo info;
86             info.name = "spimtx";
87             info.extension = "spimtx";
88             info.capabilities = FORMAT_CAPABILITY_READ;
89             formatInfoVec.push_back(info);
90         }
91 
92         CachedFileRcPtr
93         LocalFileFormat::Read(std::istream & istream) const
94         {
95 
96             // Read the entire file.
97             std::ostringstream fileStream;
98 
99             {
100                 const int MAX_LINE_SIZE = 4096;
101                 char lineBuffer[MAX_LINE_SIZE];
102 
103                 while (istream.good())
104                 {
105                     istream.getline(lineBuffer, MAX_LINE_SIZE);
106                     fileStream << std::string(lineBuffer) << " ";
107                 }
108             }
109 
110             // Turn it into parts
111             std::vector<std::string> lineParts;
112             pystring::split(pystring::strip(fileStream.str()), lineParts);
113             if(lineParts.size() != 12)
114             {
115                 std::ostringstream os;
116                 os << "Error parsing .spimtx file. ";
117                 os << "File must contain 12 float entries. ";
118                 os << lineParts.size() << " found.";
119                 throw Exception(os.str().c_str());
120             }
121 
122             // Turn the parts into floats
123             std::vector<float> floatArray;
124             if(!StringVecToFloatVec(floatArray, lineParts))
125             {
126                 std::ostringstream os;
127                 os << "Error parsing .spimtx file. ";
128                 os << "File must contain all float entries. ";
129                 throw Exception(os.str().c_str());
130             }
131 
132 
133             // Put the bits in the right place
134             LocalCachedFileRcPtr cachedFile = LocalCachedFileRcPtr(new LocalCachedFile());
135 
136             cachedFile->m44[0] = floatArray[0];
137             cachedFile->m44[1] = floatArray[1];
138             cachedFile->m44[2] = floatArray[2];
139             cachedFile->m44[3] = 0.0f;
140 
141             cachedFile->m44[4] = floatArray[4];
142             cachedFile->m44[5] = floatArray[5];
143             cachedFile->m44[6] = floatArray[6];
144             cachedFile->m44[7] = 0.0f;
145 
146             cachedFile->m44[8] = floatArray[8];
147             cachedFile->m44[9] = floatArray[9];
148             cachedFile->m44[10] = floatArray[10];
149             cachedFile->m44[11] = 0.0f;
150 
151             cachedFile->m44[12] = 0.0f;
152             cachedFile->m44[13] = 0.0f;
153             cachedFile->m44[14] = 0.0f;
154             cachedFile->m44[15] = 1.0f;
155 
156             cachedFile->offset4[0] = floatArray[3] / 65535.0f;
157             cachedFile->offset4[1] = floatArray[7] / 65535.0f;
158             cachedFile->offset4[2] = floatArray[11] / 65535.0f;
159             cachedFile->offset4[3] = 0.0f;
160 
161             return cachedFile;
162         }
163 
164         void LocalFileFormat::BuildFileOps(OpRcPtrVec & ops,
165                                       const Config& /*config*/,
166                                       const ConstContextRcPtr & /*context*/,
167                                       CachedFileRcPtr untypedCachedFile,
168                                       const FileTransform& fileTransform,
169                                       TransformDirection dir) const
170         {
171             LocalCachedFileRcPtr cachedFile = DynamicPtrCast<LocalCachedFile>(untypedCachedFile);
172 
173             if(!cachedFile) // This should never happen.
174             {
175                 std::ostringstream os;
176                 os << "Cannot build SpiMtx Ops. Invalid cache type.";
177                 throw Exception(os.str().c_str());
178             }
179 
180             TransformDirection newDir = CombineTransformDirections(dir,
181                 fileTransform.getDirection());
182 
183             CreateMatrixOffsetOp(ops,
184                                  cachedFile->m44,
185                                  cachedFile->offset4,
186                                  newDir);
187         }
188     }
189 
190     FileFormat * CreateFileFormatSpiMtx()
191     {
192         return new LocalFileFormat();
193     }
194 }
195 OCIO_NAMESPACE_EXIT
196