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