summaryrefslogtreecommitdiff
path: root/gpr/source/lib/dng_sdk/dng_area_task.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'gpr/source/lib/dng_sdk/dng_area_task.cpp')
-rw-r--r--gpr/source/lib/dng_sdk/dng_area_task.cpp270
1 files changed, 270 insertions, 0 deletions
diff --git a/gpr/source/lib/dng_sdk/dng_area_task.cpp b/gpr/source/lib/dng_sdk/dng_area_task.cpp
new file mode 100644
index 0000000..25b100e
--- /dev/null
+++ b/gpr/source/lib/dng_sdk/dng_area_task.cpp
@@ -0,0 +1,270 @@
+/*****************************************************************************/
+// Copyright 2006-2012 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_area_task.cpp#1 $ */
+/* $DateTime: 2012/05/30 13:28:51 $ */
+/* $Change: 832332 $ */
+/* $Author: tknoll $ */
+
+/*****************************************************************************/
+
+#include "dng_area_task.h"
+
+#include "dng_abort_sniffer.h"
+#include "dng_flags.h"
+#include "dng_sdk_limits.h"
+#include "dng_tile_iterator.h"
+#include "dng_utils.h"
+
+#if qImagecore
+extern bool gPrintTimings;
+#endif
+
+/*****************************************************************************/
+
+dng_area_task::dng_area_task ()
+
+ : fMaxThreads (kMaxMPThreads)
+
+ , fMinTaskArea (256 * 256)
+
+ , fUnitCell (1, 1)
+
+ , fMaxTileSize (256, 256)
+
+ {
+
+ }
+
+/*****************************************************************************/
+
+dng_area_task::~dng_area_task ()
+ {
+
+ }
+
+/*****************************************************************************/
+
+dng_rect dng_area_task::RepeatingTile1 () const
+ {
+
+ return dng_rect ();
+
+ }
+
+/*****************************************************************************/
+
+dng_rect dng_area_task::RepeatingTile2 () const
+ {
+
+ return dng_rect ();
+
+ }
+
+/*****************************************************************************/
+
+dng_rect dng_area_task::RepeatingTile3 () const
+ {
+
+ return dng_rect ();
+
+ }
+
+/*****************************************************************************/
+
+void dng_area_task::Start (uint32 /* threadCount */,
+ const dng_point & /* tileSize */,
+ dng_memory_allocator * /* allocator */,
+ dng_abort_sniffer * /* sniffer */)
+ {
+
+ }
+
+/*****************************************************************************/
+
+void dng_area_task::Finish (uint32 /* threadCount */)
+ {
+
+ }
+
+/*****************************************************************************/
+
+dng_point dng_area_task::FindTileSize (const dng_rect &area) const
+ {
+
+ dng_rect repeatingTile1 = RepeatingTile1 ();
+ dng_rect repeatingTile2 = RepeatingTile2 ();
+ dng_rect repeatingTile3 = RepeatingTile3 ();
+
+ if (repeatingTile1.IsEmpty ())
+ {
+ repeatingTile1 = area;
+ }
+
+ if (repeatingTile2.IsEmpty ())
+ {
+ repeatingTile2 = area;
+ }
+
+ if (repeatingTile3.IsEmpty ())
+ {
+ repeatingTile3 = area;
+ }
+
+ uint32 repeatV = Min_uint32 (Min_uint32 (repeatingTile1.H (),
+ repeatingTile2.H ()),
+ repeatingTile3.H ());
+
+ uint32 repeatH = Min_uint32 (Min_uint32 (repeatingTile1.W (),
+ repeatingTile2.W ()),
+ repeatingTile3.W ());
+
+ dng_point maxTileSize = MaxTileSize ();
+
+ dng_point tileSize;
+
+ tileSize.v = Min_int32 (repeatV, maxTileSize.v);
+ tileSize.h = Min_int32 (repeatH, maxTileSize.h);
+
+ // What this is doing is, if the smallest repeating image tile is larger than the
+ // maximum tile size, adjusting the tile size down so that the tiles are as small
+ // as possible while still having the same number of tiles covering the
+ // repeat area. This makes the areas more equal in size, making MP
+ // algorithms work better.
+
+ // The image core team did not understand this code, and disabled it.
+ // Really stupid idea to turn off code you don't understand!
+ // I'm undoing this removal, because I think the code is correct and useful.
+
+ uint32 countV = (repeatV + tileSize.v - 1) / tileSize.v;
+ uint32 countH = (repeatH + tileSize.h - 1) / tileSize.h;
+
+ tileSize.v = (repeatV + countV - 1) / countV;
+ tileSize.h = (repeatH + countH - 1) / countH;
+
+ // Round up to unit cell size.
+
+ dng_point unitCell = UnitCell ();
+
+ if (unitCell.h != 1 || unitCell.v != 1)
+ {
+ tileSize.v = ((tileSize.v + unitCell.v - 1) / unitCell.v) * unitCell.v;
+ tileSize.h = ((tileSize.h + unitCell.h - 1) / unitCell.h) * unitCell.h;
+ }
+
+ // But if that is larger than maximum tile size, round down to unit cell size.
+
+ if (tileSize.v > maxTileSize.v)
+ {
+ tileSize.v = (maxTileSize.v / unitCell.v) * unitCell.v;
+ }
+
+ if (tileSize.h > maxTileSize.h)
+ {
+ tileSize.h = (maxTileSize.h / unitCell.h) * unitCell.h;
+ }
+
+ #if qImagecore
+ if (gPrintTimings)
+ {
+ fprintf (stdout, "\nRender tile for below: %d x %d\n", (int32) tileSize.h, (int32) tileSize.v);
+ }
+ #endif
+
+ return tileSize;
+
+ }
+
+/*****************************************************************************/
+
+void dng_area_task::ProcessOnThread (uint32 threadIndex,
+ const dng_rect &area,
+ const dng_point &tileSize,
+ dng_abort_sniffer *sniffer)
+ {
+
+ dng_rect repeatingTile1 = RepeatingTile1 ();
+ dng_rect repeatingTile2 = RepeatingTile2 ();
+ dng_rect repeatingTile3 = RepeatingTile3 ();
+
+ if (repeatingTile1.IsEmpty ())
+ {
+ repeatingTile1 = area;
+ }
+
+ if (repeatingTile2.IsEmpty ())
+ {
+ repeatingTile2 = area;
+ }
+
+ if (repeatingTile3.IsEmpty ())
+ {
+ repeatingTile3 = area;
+ }
+
+ dng_rect tile1;
+
+ dng_tile_iterator iter1 (repeatingTile3, area);
+
+ while (iter1.GetOneTile (tile1))
+ {
+
+ dng_rect tile2;
+
+ dng_tile_iterator iter2 (repeatingTile2, tile1);
+
+ while (iter2.GetOneTile (tile2))
+ {
+
+ dng_rect tile3;
+
+ dng_tile_iterator iter3 (repeatingTile1, tile2);
+
+ while (iter3.GetOneTile (tile3))
+ {
+
+ dng_rect tile4;
+
+ dng_tile_iterator iter4 (tileSize, tile3);
+
+ while (iter4.GetOneTile (tile4))
+ {
+
+ dng_abort_sniffer::SniffForAbort (sniffer);
+
+ Process (threadIndex, tile4, sniffer);
+
+ }
+
+ }
+
+ }
+
+ }
+
+ }
+
+/*****************************************************************************/
+
+void dng_area_task::Perform (dng_area_task &task,
+ const dng_rect &area,
+ dng_memory_allocator *allocator,
+ dng_abort_sniffer *sniffer)
+ {
+
+ dng_point tileSize (task.FindTileSize (area));
+
+ task.Start (1, tileSize, allocator, sniffer);
+
+ task.ProcessOnThread (0, area, tileSize, sniffer);
+
+ task.Finish (1);
+
+ }
+
+/*****************************************************************************/