1 /*****************************************************************************/
2 // Copyright 2008-2009 Adobe Systems Incorporated
3 // All Rights Reserved.
4 //
5 // NOTICE:  Adobe permits you to use, modify, and distribute this file in
6 // accordance with the terms of the Adobe license agreement accompanying it.
7 /*****************************************************************************/
8 
9 /* $Id: //mondo/dng_sdk_1_4/dng_sdk/source/dng_opcode_list.cpp#1 $ */
10 /* $DateTime: 2012/05/30 13:28:51 $ */
11 /* $Change: 832332 $ */
12 /* $Author: tknoll $ */
13 
14 /*****************************************************************************/
15 
16 #include "dng_opcode_list.h"
17 
18 #include "dng_globals.h"
19 #include "dng_host.h"
20 #include "dng_memory_stream.h"
21 #include "dng_negative.h"
22 #include "dng_tag_values.h"
23 #include "dng_utils.h"
24 
25 #include <algorithm>
26 
27 /*****************************************************************************/
28 
dng_opcode_list(uint32 stage)29 dng_opcode_list::dng_opcode_list (uint32 stage)
30 
31 	:	fList        ()
32 	,	fAlwaysApply (false)
33 	,	fStage		 (stage)
34 
35 	{
36 
37 	}
38 
39 /******************************************************************************/
40 
~dng_opcode_list()41 dng_opcode_list::~dng_opcode_list ()
42 	{
43 
44 	Clear ();
45 
46 	}
47 
48 /******************************************************************************/
49 
Clear()50 void dng_opcode_list::Clear ()
51 	{
52 
53 	for (size_t index = 0; index < fList.size (); index++)
54 		{
55 
56 		if (fList [index])
57 			{
58 
59 			delete fList [index];
60 
61 			fList [index] = NULL;
62 
63 			}
64 
65 		}
66 
67 	fList.clear ();
68 
69 	fAlwaysApply = false;
70 
71 	}
72 
73 /******************************************************************************/
74 
Swap(dng_opcode_list & otherList)75 void dng_opcode_list::Swap (dng_opcode_list &otherList)
76 	{
77 
78 	fList.swap (otherList.fList);
79 
80 	std::swap (fAlwaysApply, otherList.fAlwaysApply);
81 
82 	std::swap (fStage, otherList.fStage);
83 
84 	}
85 
86 /******************************************************************************/
87 
MinVersion(bool includeOptional) const88 uint32 dng_opcode_list::MinVersion (bool includeOptional) const
89 	{
90 
91 	uint32 result = dngVersion_None;
92 
93 	for (size_t index = 0; index < fList.size (); index++)
94 		{
95 
96 		if (includeOptional || !fList [index]->Optional ())
97 			{
98 
99 			result = Max_uint32 (result, fList [index]->MinVersion ());
100 
101 			}
102 
103 		}
104 
105 	return result;
106 
107 	}
108 
109 /*****************************************************************************/
110 
Apply(dng_host & host,dng_negative & negative,AutoPtr<dng_image> & image)111 void dng_opcode_list::Apply (dng_host &host,
112 							 dng_negative &negative,
113 							 AutoPtr<dng_image> &image)
114 	{
115 
116 	for (uint32 index = 0; index < Count (); index++)
117 		{
118 
119 		dng_opcode &opcode (Entry (index));
120 
121 		if (opcode.AboutToApply (host, negative))
122 			{
123 
124 			opcode.Apply (host,
125 						  negative,
126 						  image);
127 
128 			}
129 
130 		}
131 
132 	}
133 
134 /*****************************************************************************/
135 
Append(AutoPtr<dng_opcode> & opcode)136 void dng_opcode_list::Append (AutoPtr<dng_opcode> &opcode)
137 	{
138 
139 	if (opcode->OpcodeID () == dngOpcode_Private)
140 		{
141 		SetAlwaysApply ();
142 		}
143 
144 	opcode->SetStage (fStage);
145 
146 	fList.push_back (NULL);
147 
148 	fList [fList.size () - 1] = opcode.Release ();
149 
150 	}
151 
152 /*****************************************************************************/
153 
Spool(dng_host & host) const154 dng_memory_block * dng_opcode_list::Spool (dng_host &host) const
155 	{
156 
157 	if (IsEmpty ())
158 		{
159 		return NULL;
160 		}
161 
162 	if (AlwaysApply ())
163 		{
164 		ThrowProgramError ();
165 		}
166 
167 	dng_memory_stream stream (host.Allocator ());
168 
169 	stream.SetBigEndian ();
170 
171 	stream.Put_uint32 ((uint32) fList.size ());
172 
173 	for (size_t index = 0; index < fList.size (); index++)
174 		{
175 
176 		stream.Put_uint32 (fList [index]->OpcodeID   ());
177 		stream.Put_uint32 (fList [index]->MinVersion ());
178 		stream.Put_uint32 (fList [index]->Flags      ());
179 
180 		fList [index]->PutData (stream);
181 
182 		}
183 
184 	return stream.AsMemoryBlock (host.Allocator ());
185 
186 	}
187 
188 /*****************************************************************************/
189 
FingerprintToStream(dng_stream & stream) const190 void dng_opcode_list::FingerprintToStream (dng_stream &stream) const
191 	{
192 
193 	if (IsEmpty ())
194 		{
195 		return;
196 		}
197 
198 	stream.Put_uint32 ((uint32) fList.size ());
199 
200 	for (size_t index = 0; index < fList.size (); index++)
201 		{
202 
203 		stream.Put_uint32 (fList [index]->OpcodeID   ());
204 		stream.Put_uint32 (fList [index]->MinVersion ());
205 		stream.Put_uint32 (fList [index]->Flags      ());
206 
207 		if (fList [index]->OpcodeID () != dngOpcode_Private)
208 			{
209 
210 			fList [index]->PutData (stream);
211 
212 			}
213 
214 		}
215 
216 	}
217 
218 /*****************************************************************************/
219 
Parse(dng_host & host,dng_stream & stream,uint32 byteCount,uint64 streamOffset)220 void dng_opcode_list::Parse (dng_host &host,
221 							 dng_stream &stream,
222 							 uint32 byteCount,
223 							 uint64 streamOffset)
224 	{
225 
226 	Clear ();
227 
228 	TempBigEndian tempBigEndian (stream);
229 
230 	stream.SetReadPosition (streamOffset);
231 
232 	uint32 count = stream.Get_uint32 ();
233 
234 	#if qDNGValidate
235 
236 	if (gVerbose)
237 		{
238 
239 		if (count == 1)
240 			{
241 			printf ("1 opcode\n");
242 			}
243 
244 		else
245 			{
246 			printf ("%u opcodes\n", (unsigned) count);
247 			}
248 
249 		}
250 
251 	#endif
252 
253 	for (uint32 index = 0; index < count; index++)
254 		{
255 
256 		uint32 opcodeID = stream.Get_uint32 ();
257 
258 		AutoPtr<dng_opcode> opcode (host.Make_dng_opcode (opcodeID,
259 														  stream));
260 
261 		Append (opcode);
262 
263 		}
264 
265 	if (stream.Position () != streamOffset + byteCount)
266 		{
267 
268 		ThrowBadFormat ("Error parsing opcode list");
269 
270 		}
271 
272 	}
273 
274 /*****************************************************************************/
275