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 | |
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 | |
41 | dng_opcode_list::~dng_opcode_list () |
42 | { |
43 | |
44 | Clear (); |
45 | |
46 | } |
47 | |
48 | /******************************************************************************/ |
49 | |
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 | |
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 | |
88 | 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 | |
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 | |
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 | |
154 | 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 | |
190 | 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 | |
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 | |