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
29dng_opcode_list::dng_opcode_list (uint32 stage)
30
31 : fList ()
32 , fAlwaysApply (false)
33 , fStage (stage)
34
35 {
36
37 }
38
39/******************************************************************************/
40
41dng_opcode_list::~dng_opcode_list ()
42 {
43
44 Clear ();
45
46 }
47
48/******************************************************************************/
49
50void 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
75void 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
88uint32 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
111void 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
136void 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
154dng_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
190void 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
220void 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