/*****************************************************************************/ // Copyright 2008-2009 Adobe Systems Incorporated // All Rights Reserved. // // NOTICE: Adobe permits you to use, modify, and distribute this file in // accordance with the terms of the Adobe license agreement accompanying it. /*****************************************************************************/ /* $Id: //mondo/dng_sdk_1_4/dng_sdk/source/dng_opcode_list.cpp#1 $ */ /* $DateTime: 2012/05/30 13:28:51 $ */ /* $Change: 832332 $ */ /* $Author: tknoll $ */ /*****************************************************************************/ #include "dng_opcode_list.h" #include "dng_globals.h" #include "dng_host.h" #include "dng_memory_stream.h" #include "dng_negative.h" #include "dng_tag_values.h" #include "dng_utils.h" #include <algorithm> /*****************************************************************************/ dng_opcode_list::dng_opcode_list (uint32 stage) : fList () , fAlwaysApply (false) , fStage (stage) { } /******************************************************************************/ dng_opcode_list::~dng_opcode_list () { Clear (); } /******************************************************************************/ void dng_opcode_list::Clear () { for (size_t index = 0; index < fList.size (); index++) { if (fList [index]) { delete fList [index]; fList [index] = NULL; } } fList.clear (); fAlwaysApply = false; } /******************************************************************************/ void dng_opcode_list::Swap (dng_opcode_list &otherList) { fList.swap (otherList.fList); std::swap (fAlwaysApply, otherList.fAlwaysApply); std::swap (fStage, otherList.fStage); } /******************************************************************************/ uint32 dng_opcode_list::MinVersion (bool includeOptional) const { uint32 result = dngVersion_None; for (size_t index = 0; index < fList.size (); index++) { if (includeOptional || !fList [index]->Optional ()) { result = Max_uint32 (result, fList [index]->MinVersion ()); } } return result; } /*****************************************************************************/ void dng_opcode_list::Apply (dng_host &host, dng_negative &negative, AutoPtr<dng_image> &image) { for (uint32 index = 0; index < Count (); index++) { dng_opcode &opcode (Entry (index)); if (opcode.AboutToApply (host, negative)) { opcode.Apply (host, negative, image); } } } /*****************************************************************************/ void dng_opcode_list::Append (AutoPtr<dng_opcode> &opcode) { if (opcode->OpcodeID () == dngOpcode_Private) { SetAlwaysApply (); } opcode->SetStage (fStage); fList.push_back (NULL); fList [fList.size () - 1] = opcode.Release (); } /*****************************************************************************/ dng_memory_block * dng_opcode_list::Spool (dng_host &host) const { if (IsEmpty ()) { return NULL; } if (AlwaysApply ()) { ThrowProgramError (); } dng_memory_stream stream (host.Allocator ()); stream.SetBigEndian (); stream.Put_uint32 ((uint32) fList.size ()); for (size_t index = 0; index < fList.size (); index++) { stream.Put_uint32 (fList [index]->OpcodeID ()); stream.Put_uint32 (fList [index]->MinVersion ()); stream.Put_uint32 (fList [index]->Flags ()); fList [index]->PutData (stream); } return stream.AsMemoryBlock (host.Allocator ()); } /*****************************************************************************/ void dng_opcode_list::FingerprintToStream (dng_stream &stream) const { if (IsEmpty ()) { return; } stream.Put_uint32 ((uint32) fList.size ()); for (size_t index = 0; index < fList.size (); index++) { stream.Put_uint32 (fList [index]->OpcodeID ()); stream.Put_uint32 (fList [index]->MinVersion ()); stream.Put_uint32 (fList [index]->Flags ()); if (fList [index]->OpcodeID () != dngOpcode_Private) { fList [index]->PutData (stream); } } } /*****************************************************************************/ void dng_opcode_list::Parse (dng_host &host, dng_stream &stream, uint32 byteCount, uint64 streamOffset) { Clear (); TempBigEndian tempBigEndian (stream); stream.SetReadPosition (streamOffset); uint32 count = stream.Get_uint32 (); #if qDNGValidate if (gVerbose) { if (count == 1) { printf ("1 opcode\n"); } else { printf ("%u opcodes\n", (unsigned) count); } } #endif for (uint32 index = 0; index < count; index++) { uint32 opcodeID = stream.Get_uint32 (); AutoPtr<dng_opcode> opcode (host.Make_dng_opcode (opcodeID, stream)); Append (opcode); } if (stream.Position () != streamOffset + byteCount) { ThrowBadFormat ("Error parsing opcode list"); } } /*****************************************************************************/