275 lines
5.1 KiB
C++
275 lines
5.1 KiB
C++
/*****************************************************************************/
|
|
// 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");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
/*****************************************************************************/
|