1 ///////////////////////////////////////////////////////////////////////////
2 // Copyright (c) 2013 Academy of Motion Picture Arts and Sciences
3 // ("A.M.P.A.S."). Portions contributed by others as indicated.
4 // All rights reserved.
5 //
6 // A worldwide, royalty-free, non-exclusive right to copy, modify, create
7 // derivatives, and use, in source and binary forms, is hereby granted,
8 // subject to acceptance of this license. Performance of any of the
9 // aforementioned acts indicates acceptance to be bound by the following
10 // terms and conditions:
11 //
12 //  * Copies of source code, in whole or in part, must retain the
13 //    above copyright notice, this list of conditions and the
14 //    Disclaimer of Warranty.
15 //
16 //  * Use in binary form must retain the above copyright notice,
17 //    this list of conditions and the Disclaimer of Warranty in the
18 //    documentation and/or other materials provided with the distribution.
19 //
20 //  * Nothing in this license shall be deemed to grant any rights to
21 //    trademarks, copyrights, patents, trade secrets or any other
22 //    intellectual property of A.M.P.A.S. or any contributors, except
23 //    as expressly stated herein.
24 //
25 //  * Neither the name "A.M.P.A.S." nor the name of any other
26 //    contributors to this software may be used to endorse or promote
27 //    products derivative of or based on this software without express
28 //    prior written permission of A.M.P.A.S. or the contributors, as
29 //    appropriate.
30 //
31 // This license shall be construed pursuant to the laws of the State of
32 // California, and any disputes related thereto shall be subject to the
33 // jurisdiction of the courts therein.
34 //
35 // Disclaimer of Warranty: THIS SOFTWARE IS PROVIDED BY A.M.P.A.S. AND
36 // CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,
37 // BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS
38 // FOR A PARTICULAR PURPOSE, AND NON-INFRINGEMENT ARE DISCLAIMED. IN NO
39 // EVENT SHALL A.M.P.A.S., OR ANY CONTRIBUTORS OR DISTRIBUTORS, BE LIABLE
40 // FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, RESITUTIONARY,
41 // OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
42 // SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
43 // INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
44 // CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
45 // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
46 // THE POSSIBILITY OF SUCH DAMAGE.
47 //
48 // WITHOUT LIMITING THE GENERALITY OF THE FOREGOING, THE ACADEMY
49 // SPECIFICALLY DISCLAIMS ANY REPRESENTATIONS OR WARRANTIES WHATSOEVER
50 // RELATED TO PATENT OR OTHER INTELLECTUAL PROPERTY RIGHTS IN THE ACADEMY
51 // COLOR ENCODING SYSTEM, OR APPLICATIONS THEREOF, HELD BY PARTIES OTHER
52 // THAN A.M.P.A.S., WHETHER DISCLOSED OR UNDISCLOSED.
53 ///////////////////////////////////////////////////////////////////////////
54 
55 #include "aces_file.hh"
56 #include <iostream>
57 
58 #if defined( HAVE_ACESFILE )
59 #include <aces_Writer.h>
60 #include <stdexcept>
61 #include <half.h>
62 
aces_write(const char * name,float scale,uint32_t width,uint32_t height,uint32_t channels,const float * pixels,format_t * format)63 void aces_write(const char *name, float scale,
64                uint32_t width, uint32_t height, uint32_t channels,
65                const float *pixels,
66                format_t *format) {
67 
68 	std::vector<halfBytes> scaled_pixels;
69 
70     {
71         float const *in = pixels;
72         if (scale == 0.0f) scale = 1.0f;
73 
74         scaled_pixels.resize(height*width*channels);
75         halfBytes *out = &scaled_pixels[0];
76         for(size_t i=0; i<scaled_pixels.size(); i++) {
77 			half tmpV( *(in++) / scale );
78             *(out++)=tmpV.bits();
79         }
80     }
81 
82     halfBytes *in = &scaled_pixels[0];
83 
84     std::vector<std::string> filenames;
85 	filenames.push_back( name );
86 
87 	aces_Writer x;
88 
89 	MetaWriteClip writeParams;
90 
91 	writeParams.duration				= 1;
92 	writeParams.outputFilenames			= filenames;
93 
94 	writeParams.outputRows				= height;
95 	writeParams.outputCols				= width;
96 
97 	writeParams.hi = x.getDefaultHeaderInfo();
98 	writeParams.hi.originalImageFlag	= 1;
99 	writeParams.hi.software				= "ctlrender";
100 
101 	writeParams.hi.channels.clear();
102 	switch ( channels )
103 	{
104 		case 3:
105 			writeParams.hi.channels.resize(3);
106 			writeParams.hi.channels[0].name = "B";
107 			writeParams.hi.channels[1].name = "G";
108 			writeParams.hi.channels[2].name = "R";
109 			break;
110 		case 4:
111 			writeParams.hi.channels.resize(4);
112 			writeParams.hi.channels[0].name = "A";
113 			writeParams.hi.channels[1].name = "B";
114 			writeParams.hi.channels[2].name = "G";
115 			writeParams.hi.channels[3].name = "R";
116 			break;
117 		case 6:
118 			throw std::invalid_argument("Stereo RGB support not yet implemented");
119 //			writeParams.hi.channels.resize(6);
120 //			writeParams.hi.channels[0].name = "B";
121 //			writeParams.hi.channels[1].name = "G";
122 //			writeParams.hi.channels[2].name = "R";
123 //			writeParams.hi.channels[3].name = "left.B";
124 //			writeParams.hi.channels[4].name = "left.G";
125 //			writeParams.hi.channels[5].name = "left.R";
126 //			break;
127 		case 8:
128 			throw std::invalid_argument("Stereo RGB support not yet implemented");
129 //			writeParams.hi.channels.resize(8);
130 //			writeParams.hi.channels[0].name = "A";
131 //			writeParams.hi.channels[1].name = "B";
132 //			writeParams.hi.channels[2].name = "G";
133 //			writeParams.hi.channels[3].name = "R";
134 //			writeParams.hi.channels[4].name = "left.A";
135 //			writeParams.hi.channels[5].name = "left.B";
136 //			writeParams.hi.channels[6].name = "left.G";
137 //			writeParams.hi.channels[7].name = "left.R";
138 //			break;
139 		default:
140 			throw std::invalid_argument("Only RGB, RGBA or stereo RGB[A] file supported");
141 			break;
142 	}
143 
144 	DynamicMetadata dynamicMeta;
145 	dynamicMeta.imageIndex = 0;
146 	dynamicMeta.imageCounter = 0;
147 
148 	x.configure ( writeParams );
149 	x.newImageObject ( dynamicMeta );
150 
151 	for ( uint32 row = 0; row < height; row++) {
152 		halfBytes *rgbData = in + width*channels*row;
153 		x.storeHalfRow ( rgbData, row );
154 	}
155 
156 #if 0
157 	std::cout << "saving aces file" << std::endl;
158 	std::cout << "size " << width << "x" << height << "x" << channels << std::endl;
159 	std::cout << "size " << writeParams.outputCols << "x" << writeParams.outputRows << std::endl;
160 	std::cout << "duration " << writeParams.duration << std::endl;
161 	std::cout << writeParams.hi;
162 	std::cout << "\ndynamic meta" << std::endl;
163 	std::cout << "imageIndex " << dynamicMeta.imageIndex << std::endl;
164 	std::cout << "imageCounter " << dynamicMeta.imageCounter << std::endl;
165 	std::cout << "timeCode " << dynamicMeta.timeCode << std::endl;
166 	std::cout << "keyCode " << dynamicMeta.keyCode << std::endl;
167 	std::cout << "capDate " << dynamicMeta.capDate << std::endl;
168 	std::cout << "uuid " << dynamicMeta.uuid << std::endl;
169 #endif
170 
171 	x.saveImageObject ( );
172 }
173 
174 #else
175 
aces_write(const char * name,float scale,uint32_t width,uint32_t height,uint32_t channels,const float * pixels,format_t * format)176 void aces_write(const char *name, float scale,
177                 uint32_t width, uint32_t height, uint32_t channels,
178                 const float *pixels,
179                 format_t *format)
180 {
181 	std::cerr << "AcesContainer library not found" << std::endl;
182 }
183 
184 #endif
185 
186 
187