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