1 /*****************************************************************************/
2 // Copyright 2008 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_opcodes.h#2 $ */
10 /* $DateTime: 2012/08/02 06:09:06 $ */
11 /* $Change: 841096 $ */
12 /* $Author: erichan $ */
13 
14 /** \file
15  * Base class and common data structures for opcodes (introduced in DNG 1.3).
16  */
17 
18 /*****************************************************************************/
19 
20 #ifndef __dng_opcodes__
21 #define __dng_opcodes__
22 
23 /*****************************************************************************/
24 
25 #include "dng_auto_ptr.h"
26 #include "dng_classes.h"
27 #include "dng_rect.h"
28 #include "dng_types.h"
29 
30 /*****************************************************************************/
31 
32 /// \brief List of supported opcodes (by ID).
33 
34 enum dng_opcode_id
35 	{
36 
37 	// Internal use only opcode.  Never written to DNGs.
38 
39 	dngOpcode_Private				= 0,
40 
41 	// Warp image to correct distortion and lateral chromatic aberration for
42 	// rectilinear lenses.
43 
44 	dngOpcode_WarpRectilinear 		= 1,
45 
46 	// Warp image to correction distortion for fisheye lenses (i.e., map the
47 	// fisheye projection to a perspective projection).
48 
49 	dngOpcode_WarpFisheye			= 2,
50 
51 	// Radial vignette correction.
52 
53 	dngOpcode_FixVignetteRadial		= 3,
54 
55 	// Patch bad Bayer pixels which are marked with a special value in the image.
56 
57 	dngOpcode_FixBadPixelsConstant  = 4,
58 
59 	// Patch bad Bayer pixels/rectangles at a list of specified coordinates.
60 
61 	dngOpcode_FixBadPixelsList		= 5,
62 
63 	// Trim image to specified bounds.
64 
65 	dngOpcode_TrimBounds			= 6,
66 
67 	// Map an area through a 16-bit LUT.
68 
69 	dngOpcode_MapTable				= 7,
70 
71 	// Map an area using a polynomial function.
72 
73 	dngOpcode_MapPolynomial			= 8,
74 
75 	// Apply a gain map to an area.
76 
77 	dngOpcode_GainMap				= 9,
78 
79 	// Apply a per-row delta to an area.
80 
81 	dngOpcode_DeltaPerRow			= 10,
82 
83 	// Apply a per-column delta to an area.
84 
85 	dngOpcode_DeltaPerColumn		= 11,
86 
87 	// Apply a per-row scale to an area.
88 
89 	dngOpcode_ScalePerRow			= 12,
90 
91 	// Apply a per-column scale to an area.
92 
93 	dngOpcode_ScalePerColumn		= 13
94 
95 	};
96 
97 /*****************************************************************************/
98 
99 /// \brief Virtual base class for opcode.
100 
101 class dng_opcode
102 	{
103 
104 	public:
105 
106 		/// Opcode flags.
107 
108 		enum
109 			{
110 			kFlag_None			= 0,	//!< No flag.
111 			kFlag_Optional      = 1,	//!< This opcode is optional.
112 			kFlag_SkipIfPreview = 2		//!< May skip opcode for preview images.
113 			};
114 
115 	private:
116 
117 		uint32 fOpcodeID;
118 
119 		uint32 fMinVersion;
120 
121 		uint32 fFlags;
122 
123 		bool fWasReadFromStream;
124 
125 		uint32 fStage;
126 
127 	protected:
128 
129 		dng_opcode (uint32 opcodeID,
130 					uint32 minVersion,
131 					uint32 flags);
132 
133 		dng_opcode (uint32 opcodeID,
134 					dng_stream &stream,
135 					const char *name);
136 
137 	public:
138 
139 		virtual ~dng_opcode ();
140 
141 		/// The ID of this opcode.
142 
OpcodeID()143 		uint32 OpcodeID () const
144 			{
145 			return fOpcodeID;
146 			}
147 
148 		/// The first DNG version that supports this opcode.
149 
MinVersion()150 		uint32 MinVersion () const
151 			{
152 			return fMinVersion;
153 			}
154 
155 		/// The flags for this opcode.
156 
Flags()157 		uint32 Flags () const
158 			{
159 			return fFlags;
160 			}
161 
162 		/// Is this opcode optional?
163 
Optional()164 		bool Optional () const
165 			{
166 			return (Flags () & kFlag_Optional) != 0;
167 			}
168 
169 		/// Should the opcode be skipped when rendering preview images?
170 
SkipIfPreview()171 		bool SkipIfPreview () const
172 			{
173 			return (Flags () & kFlag_SkipIfPreview) != 0;
174 			}
175 
176 		/// Was this opcode read from a data stream?
177 
WasReadFromStream()178 		bool WasReadFromStream () const
179 			{
180 			return fWasReadFromStream;
181 			}
182 
183 		/// Which image processing stage (1, 2, 3) is associated with this
184 		/// opcode?
185 
Stage()186 		uint32 Stage () const
187 			{
188 			return fStage;
189 			}
190 
191 		/// Set the image processing stage (1, 2, 3) for this opcode. Stage 1 is
192 		/// the original image data, including masked areas. Stage 2 is
193 		/// linearized image data and trimmed to the active area. Stage 3 is
194 		/// demosaiced and trimmed to the active area.
195 
SetStage(uint32 stage)196 		void SetStage (uint32 stage)
197 			{
198 			fStage = stage;
199 			}
200 
201 		/// Is the opcode a NOP (i.e., does nothing)? An opcode could be a NOP
202 		/// for some specific parameters.
203 
IsNOP()204 		virtual bool IsNOP () const
205 			{
206 			return false;
207 			}
208 
209 		/// Is this opcode valid for the specified negative?
210 
IsValidForNegative(const dng_negative &)211 		virtual bool IsValidForNegative (const dng_negative & /* negative */) const
212 			{
213 			return true;
214 			}
215 
216 		/// Write opcode to a stream.
217 		/// \param stream The stream to which to write the opcode data.
218 
219 		virtual void PutData (dng_stream &stream) const;
220 
221 		/// Perform error checking prior to applying this opcode to the
222 		/// specified negative. Returns true if this opcode should be applied to
223 		/// the negative, false otherwise.
224 
225 		bool AboutToApply (dng_host &host,
226 						   dng_negative &negative);
227 
228 		/// Apply this opcode to the specified image with associated negative.
229 
230 		virtual void Apply (dng_host &host,
231 							dng_negative &negative,
232 							AutoPtr<dng_image> &image) = 0;
233 
234 	};
235 
236 /*****************************************************************************/
237 
238 /// \brief Class to represent unknown opcodes (e.g, opcodes defined in future
239 /// DNG versions).
240 
241 class dng_opcode_Unknown: public dng_opcode
242 	{
243 
244 	private:
245 
246 		AutoPtr<dng_memory_block> fData;
247 
248 	public:
249 
250 		dng_opcode_Unknown (dng_host &host,
251 							uint32 opcodeID,
252 							dng_stream &stream);
253 
254 		virtual void PutData (dng_stream &stream) const;
255 
256 		virtual void Apply (dng_host &host,
257 							dng_negative &negative,
258 							AutoPtr<dng_image> &image);
259 
260 	};
261 
262 /*****************************************************************************/
263 
264 /// \brief Class to represent a filter opcode, such as a convolution.
265 
266 class dng_filter_opcode: public dng_opcode
267 	{
268 
269 	protected:
270 
271 		dng_filter_opcode (uint32 opcodeID,
272 						   uint32 minVersion,
273 						   uint32 flags);
274 
275 		dng_filter_opcode (uint32 opcodeID,
276 						   dng_stream &stream,
277 						   const char *name);
278 
279 	public:
280 
281 		/// The pixel data type of this opcode.
282 
BufferPixelType(uint32 imagePixelType)283 		virtual uint32 BufferPixelType (uint32 imagePixelType)
284 			{
285 			return imagePixelType;
286 			}
287 
288 		/// The adjusted bounds (processing area) of this opcode. It is limited to
289 		/// the intersection of the specified image area and the GainMap area.
290 
ModifiedBounds(const dng_rect & imageBounds)291 		virtual dng_rect ModifiedBounds (const dng_rect &imageBounds)
292 			{
293 			return imageBounds;
294 			}
295 
296 		/// Returns the width and height (in pixels) of the repeating mosaic pattern.
297 
SrcRepeat()298 		virtual dng_point SrcRepeat ()
299 			{
300 			return dng_point (1, 1);
301 			}
302 
303 		/// Returns the source pixel area needed to process a destination pixel area
304 		/// that lies within the specified bounds.
305 		/// \param dstArea The destination pixel area to be computed.
306 		/// \param imageBounds The overall image area (dstArea will lie within these
307 		/// bounds).
308 		/// \retval The source pixel area needed to process the specified dstArea.
309 
SrcArea(const dng_rect & dstArea,const dng_rect &)310 		virtual dng_rect SrcArea (const dng_rect &dstArea,
311 								  const dng_rect & /* imageBounds */)
312 			{
313 			return dstArea;
314 			}
315 
316 		/// Given a destination tile size, calculate input tile size. Simlar to
317 		/// SrcArea, and should seldom be overridden.
318 		///
319 		/// \param dstTileSize The destination tile size that is targeted for output.
320 		///
321 		/// \param imageBounds The image bounds (the destination tile will
322 		/// always lie within these bounds).
323 		///
324 		/// \retval The source tile size needed to compute a tile of the destination
325 		/// size.
326 
SrcTileSize(const dng_point & dstTileSize,const dng_rect & imageBounds)327 		virtual dng_point SrcTileSize (const dng_point &dstTileSize,
328 									   const dng_rect &imageBounds)
329 			{
330 			return SrcArea (dng_rect (dstTileSize),
331 							imageBounds).Size ();
332 			}
333 
334 		/// Startup method called before any processing is performed on pixel areas.
335 		/// It can be used to allocate (per-thread) memory and setup tasks.
336 		///
337 		/// \param negative The negative object to be processed.
338 		///
339 		/// \param threadCount The number of threads to be used to perform the
340 		/// processing.
341 		///
342 		/// \param threadCount Total number of threads that will be used for
343 		/// processing. Less than or equal to MaxThreads.
344 		///
345 		/// \param tileSize Size of source tiles which will be processed. (Not all
346 		/// tiles will be this size due to edge conditions.)
347 		///
348 		/// \param imageBounds Total size of image to be processed.
349 		///
350 		/// \param imagePlanes Number of planes in the image. Less than or equal to
351 		/// kMaxColorPlanes.
352 		///
353 		/// \param bufferPixelType Pixel type of image buffer (see dng_tag_types.h).
354 		///
355 		/// \param allocator dng_memory_allocator to use for allocating temporary
356 		/// buffers, etc.
357 
Prepare(dng_negative &,uint32,const dng_point &,const dng_rect &,uint32,uint32,dng_memory_allocator &)358 		virtual void Prepare (dng_negative & /* negative */,
359 							  uint32 /* threadCount */,
360 							  const dng_point & /* tileSize */,
361 							  const dng_rect & /* imageBounds */,
362 							  uint32 /* imagePlanes */,
363 							  uint32 /* bufferPixelType */,
364 							  dng_memory_allocator & /* allocator */)
365 			{
366 			}
367 
368 		/// Implements filtering operation from one buffer to another. Source
369 		/// and destination pixels are set up in member fields of this class.
370 		/// Ideally, no allocation should be done in this routine.
371 		///
372 		/// \param negative The negative associated with the pixels to be
373 		/// processed.
374 		///
375 		/// \param threadIndex The thread on which this routine is being called,
376 		/// between 0 and threadCount - 1 for the threadCount passed to Prepare
377 		/// method.
378 		///
379 		/// \param srcBuffer Input area and source pixels.
380 		///
381 		/// \param dstBuffer Destination pixels.
382 		///
383 		/// \param dstArea Destination pixel processing area.
384 		///
385 		/// \param imageBounds Total image area to be processed; dstArea will
386 		/// always lie within these bounds.
387 
388 		virtual void ProcessArea (dng_negative &negative,
389 								  uint32 threadIndex,
390 								  dng_pixel_buffer &srcBuffer,
391 								  dng_pixel_buffer &dstBuffer,
392 								  const dng_rect &dstArea,
393 								  const dng_rect &imageBounds) = 0;
394 
395 		virtual void Apply (dng_host &host,
396 							dng_negative &negative,
397 							AutoPtr<dng_image> &image);
398 
399 	};
400 
401 /*****************************************************************************/
402 
403 /// \brief Class to represent an in-place (i.e., pointwise, per-pixel) opcode,
404 /// such as a global tone curve.
405 
406 class dng_inplace_opcode: public dng_opcode
407 	{
408 
409 	protected:
410 
411 		dng_inplace_opcode (uint32 opcodeID,
412 						    uint32 minVersion,
413 						    uint32 flags);
414 
415 		dng_inplace_opcode (uint32 opcodeID,
416 						    dng_stream &stream,
417 						    const char *name);
418 
419 	public:
420 
421 		/// The pixel data type of this opcode.
422 
BufferPixelType(uint32 imagePixelType)423 		virtual uint32 BufferPixelType (uint32 imagePixelType)
424 			{
425 			return imagePixelType;
426 			}
427 
428 		/// The adjusted bounds (processing area) of this opcode. It is limited to
429 		/// the intersection of the specified image area and the GainMap area.
430 
ModifiedBounds(const dng_rect & imageBounds)431 		virtual dng_rect ModifiedBounds (const dng_rect &imageBounds)
432 			{
433 			return imageBounds;
434 			}
435 
436 		/// Startup method called before any processing is performed on pixel areas.
437 		/// It can be used to allocate (per-thread) memory and setup tasks.
438 		///
439 		/// \param negative The negative object to be processed.
440 		///
441 		/// \param threadCount The number of threads to be used to perform the
442 		/// processing.
443 		///
444 		/// \param threadCount Total number of threads that will be used for
445 		/// processing. Less than or equal to MaxThreads.
446 		///
447 		/// \param tileSize Size of source tiles which will be processed. (Not all
448 		/// tiles will be this size due to edge conditions.)
449 		///
450 		/// \param imageBounds Total size of image to be processed.
451 		///
452 		/// \param imagePlanes Number of planes in the image. Less than or equal to
453 		/// kMaxColorPlanes.
454 		///
455 		/// \param bufferPixelType Pixel type of image buffer (see dng_tag_types.h).
456 		///
457 		/// \param allocator dng_memory_allocator to use for allocating temporary
458 		/// buffers, etc.
459 
Prepare(dng_negative &,uint32,const dng_point &,const dng_rect &,uint32,uint32,dng_memory_allocator &)460 		virtual void Prepare (dng_negative & /* negative */,
461 							  uint32 /* threadCount */,
462 							  const dng_point & /* tileSize */,
463 							  const dng_rect & /* imageBounds */,
464 							  uint32 /* imagePlanes */,
465 							  uint32 /* bufferPixelType */,
466 							  dng_memory_allocator & /* allocator */)
467 			{
468 			}
469 
470 		/// Implements image processing operation in a single buffer. The source
471 		/// pixels are provided as input to the buffer, and this routine
472 		/// calculates and writes the destination pixels to the same buffer.
473 		/// Ideally, no allocation should be done in this routine.
474 		///
475 		/// \param negative The negative associated with the pixels to be
476 		/// processed.
477 		///
478 		/// \param threadIndex The thread on which this routine is being called,
479 		/// between 0 and threadCount - 1 for the threadCount passed to Prepare
480 		/// method.
481 		///
482 		/// \param srcBuffer Input area and source pixels.
483 		///
484 		/// \param dstBuffer Destination pixels.
485 		///
486 		/// \param dstArea Destination pixel processing area.
487 		///
488 		/// \param imageBounds Total image area to be processed; dstArea will
489 		/// always lie within these bounds.
490 
491 		virtual void ProcessArea (dng_negative &negative,
492 								  uint32 threadIndex,
493 								  dng_pixel_buffer &buffer,
494 								  const dng_rect &dstArea,
495 								  const dng_rect &imageBounds) = 0;
496 
497 		virtual void Apply (dng_host &host,
498 							dng_negative &negative,
499 							AutoPtr<dng_image> &image);
500 
501 	};
502 
503 /*****************************************************************************/
504 
505 #endif
506 
507 /*****************************************************************************/
508