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