File indexing completed on 2025-01-19 03:55:09
0001 /*****************************************************************************/ 0002 // Copyright 2008-2019 Adobe Systems Incorporated 0003 // All Rights Reserved. 0004 // 0005 // NOTICE: Adobe permits you to use, modify, and distribute this file in 0006 // accordance with the terms of the Adobe license agreement accompanying it. 0007 /*****************************************************************************/ 0008 0009 /** \file 0010 * Base class and common data structures for opcodes (introduced in DNG 1.3). 0011 */ 0012 0013 /*****************************************************************************/ 0014 0015 #ifndef __dng_opcodes__ 0016 #define __dng_opcodes__ 0017 0018 /*****************************************************************************/ 0019 0020 #include "dng_auto_ptr.h" 0021 #include "dng_classes.h" 0022 #include "dng_rect.h" 0023 #include "dng_types.h" 0024 0025 /*****************************************************************************/ 0026 0027 /// \brief List of supported opcodes (by ID). 0028 0029 enum dng_opcode_id 0030 { 0031 0032 // Internal use only opcode. Never written to DNGs. 0033 0034 dngOpcode_Private = 0, 0035 0036 // Warp image to correct distortion and lateral chromatic aberration for 0037 // rectilinear lenses. 0038 0039 dngOpcode_WarpRectilinear = 1, 0040 0041 // Warp image to correction distortion for fisheye lenses (i.e., map the 0042 // fisheye projection to a perspective projection). 0043 0044 dngOpcode_WarpFisheye = 2, 0045 0046 // Radial vignette correction. 0047 0048 dngOpcode_FixVignetteRadial = 3, 0049 0050 // Patch bad Bayer pixels which are marked with a special value in the image. 0051 0052 dngOpcode_FixBadPixelsConstant = 4, 0053 0054 // Patch bad Bayer pixels/rectangles at a list of specified coordinates. 0055 0056 dngOpcode_FixBadPixelsList = 5, 0057 0058 // Trim image to specified bounds. 0059 0060 dngOpcode_TrimBounds = 6, 0061 0062 // Map an area through a 16-bit LUT. 0063 0064 dngOpcode_MapTable = 7, 0065 0066 // Map an area using a polynomial function. 0067 0068 dngOpcode_MapPolynomial = 8, 0069 0070 // Apply a gain map to an area. 0071 0072 dngOpcode_GainMap = 9, 0073 0074 // Apply a per-row delta to an area. 0075 0076 dngOpcode_DeltaPerRow = 10, 0077 0078 // Apply a per-column delta to an area. 0079 0080 dngOpcode_DeltaPerColumn = 11, 0081 0082 // Apply a per-row scale to an area. 0083 0084 dngOpcode_ScalePerRow = 12, 0085 0086 // Apply a per-column scale to an area. 0087 0088 dngOpcode_ScalePerColumn = 13 0089 0090 }; 0091 0092 /*****************************************************************************/ 0093 0094 /// \brief Virtual base class for opcode. 0095 0096 class dng_opcode 0097 { 0098 0099 public: 0100 0101 /// Opcode flags. 0102 0103 enum 0104 { 0105 kFlag_None = 0, //!< No flag. 0106 kFlag_Optional = 1, //!< This opcode is optional. 0107 kFlag_SkipIfPreview = 2 //!< May skip opcode for preview images. 0108 }; 0109 0110 private: 0111 0112 uint32 fOpcodeID; 0113 0114 uint32 fMinVersion; 0115 0116 uint32 fFlags; 0117 0118 bool fWasReadFromStream; 0119 0120 uint32 fStage; 0121 0122 protected: 0123 0124 dng_opcode (uint32 opcodeID, 0125 uint32 minVersion, 0126 uint32 flags); 0127 0128 dng_opcode (uint32 opcodeID, 0129 dng_stream &stream, 0130 const char *name); 0131 0132 // This helper routine will be called by AboutToApply if AboutToApply 0133 // passes its internal checking and plans to return true. This is an 0134 // opportunity for subclasses to perform some internal preparation 0135 // based on the negative, image bounds, and number of image planes. 0136 0137 virtual void DoAboutToApply (dng_host & /* host */, 0138 dng_negative & /* negative */, 0139 const dng_rect & /* imageBounds */, 0140 uint32 /* imagePlanes */) 0141 { 0142 } 0143 0144 public: 0145 0146 virtual ~dng_opcode (); 0147 0148 /// The ID of this opcode. 0149 0150 uint32 OpcodeID () const 0151 { 0152 return fOpcodeID; 0153 } 0154 0155 /// The first DNG version that supports this opcode. 0156 0157 uint32 MinVersion () const 0158 { 0159 return fMinVersion; 0160 } 0161 0162 /// The flags for this opcode. 0163 0164 uint32 Flags () const 0165 { 0166 return fFlags; 0167 } 0168 0169 /// Is this opcode optional? 0170 0171 bool Optional () const 0172 { 0173 return (Flags () & kFlag_Optional) != 0; 0174 } 0175 0176 /// Should the opcode be skipped when rendering preview images? 0177 0178 bool SkipIfPreview () const 0179 { 0180 return (Flags () & kFlag_SkipIfPreview) != 0; 0181 } 0182 0183 /// Was this opcode read from a data stream? 0184 0185 bool WasReadFromStream () const 0186 { 0187 return fWasReadFromStream; 0188 } 0189 0190 /// Which image processing stage (1, 2, 3) is associated with this 0191 /// opcode? 0192 0193 uint32 Stage () const 0194 { 0195 return fStage; 0196 } 0197 0198 /// Set the image processing stage (1, 2, 3) for this opcode. Stage 1 is 0199 /// the original image data, including masked areas. Stage 2 is 0200 /// linearized image data and trimmed to the active area. Stage 3 is 0201 /// demosaiced and trimmed to the active area. 0202 0203 void SetStage (uint32 stage) 0204 { 0205 fStage = stage; 0206 } 0207 0208 /// Is the opcode a NOP (i.e., does nothing)? An opcode could be a NOP 0209 /// for some specific parameters. 0210 0211 virtual bool IsNOP () const 0212 { 0213 return false; 0214 } 0215 0216 /// Is this opcode valid for the specified negative? 0217 0218 virtual bool IsValidForNegative (const dng_negative & /* negative */) const 0219 { 0220 return true; 0221 } 0222 0223 /// Write opcode to a stream. 0224 /// \param stream The stream to which to write the opcode data. 0225 0226 virtual void PutData (dng_stream &stream) const; 0227 0228 /// Perform error checking prior to applying this opcode to the 0229 /// specified negative. Returns true if this opcode should be applied to 0230 /// the negative, false otherwise. 0231 0232 bool AboutToApply (dng_host &host, 0233 dng_negative &negative, 0234 const dng_rect &imageBounds, 0235 uint32 imagePlanes); 0236 0237 /// Apply this opcode to the specified image with associated negative. 0238 0239 virtual void Apply (dng_host &host, 0240 dng_negative &negative, 0241 AutoPtr<dng_image> &image) = 0; 0242 0243 }; 0244 0245 /*****************************************************************************/ 0246 0247 /// \brief Class to represent unknown opcodes (e.g, opcodes defined in future 0248 /// DNG versions). 0249 0250 class dng_opcode_Unknown: public dng_opcode 0251 { 0252 0253 private: 0254 0255 AutoPtr<dng_memory_block> fData; 0256 0257 public: 0258 0259 dng_opcode_Unknown (dng_host &host, 0260 uint32 opcodeID, 0261 dng_stream &stream); 0262 0263 virtual void PutData (dng_stream &stream) const; 0264 0265 virtual void Apply (dng_host &host, 0266 dng_negative &negative, 0267 AutoPtr<dng_image> &image); 0268 0269 }; 0270 0271 /*****************************************************************************/ 0272 0273 /// \brief Class to represent a filter opcode, such as a convolution. 0274 0275 class dng_filter_opcode: public dng_opcode 0276 { 0277 0278 protected: 0279 0280 dng_filter_opcode (uint32 opcodeID, 0281 uint32 minVersion, 0282 uint32 flags); 0283 0284 dng_filter_opcode (uint32 opcodeID, 0285 dng_stream &stream, 0286 const char *name); 0287 0288 public: 0289 0290 /// The pixel data type of this opcode. 0291 0292 virtual uint32 BufferPixelType (uint32 imagePixelType) 0293 { 0294 return imagePixelType; 0295 } 0296 0297 /// The adjusted bounds (processing area) of this opcode. It is limited to 0298 /// the intersection of the specified image area and the GainMap area. 0299 0300 virtual dng_rect ModifiedBounds (const dng_rect &imageBounds) 0301 { 0302 return imageBounds; 0303 } 0304 0305 /// Returns the width and height (in pixels) of the repeating mosaic pattern. 0306 0307 virtual dng_point SrcRepeat () 0308 { 0309 return dng_point (1, 1); 0310 } 0311 0312 /// Returns the source pixel area needed to process a destination pixel area 0313 /// that lies within the specified bounds. 0314 /// \param dstArea The destination pixel area to be computed. 0315 /// \param imageBounds The overall image area (dstArea will lie within these 0316 /// bounds). 0317 /// \retval The source pixel area needed to process the specified dstArea. 0318 0319 virtual dng_rect SrcArea (const dng_rect &dstArea, 0320 const dng_rect &imageBounds) 0321 { 0322 (void) imageBounds; 0323 return dstArea; 0324 } 0325 0326 /// Given a destination tile size, calculate input tile size. Simlar to 0327 /// SrcArea, and should seldom be overridden. 0328 /// 0329 /// \param dstTileSize The destination tile size that is targeted for output. 0330 /// 0331 /// \param imageBounds The image bounds (the destination tile will 0332 /// always lie within these bounds). 0333 /// 0334 /// \retval The source tile size needed to compute a tile of the destination 0335 /// size. 0336 0337 virtual dng_point SrcTileSize (const dng_point &dstTileSize, 0338 const dng_rect &imageBounds) 0339 { 0340 return SrcArea (dng_rect (dstTileSize), 0341 imageBounds).Size (); 0342 } 0343 0344 /// Startup method called before any processing is performed on pixel areas. 0345 /// It can be used to allocate (per-thread) memory and setup tasks. 0346 /// 0347 /// \param negative The negative object to be processed. 0348 /// 0349 /// \param threadCount Total number of threads that will be used for 0350 /// processing. Less than or equal to MaxThreads. 0351 /// 0352 /// \param tileSize Size of source tiles which will be processed. (Not all 0353 /// tiles will be this size due to edge conditions.) 0354 /// 0355 /// \param imageBounds Total size of image to be processed. 0356 /// 0357 /// \param imagePlanes Number of planes in the image. Less than or equal to 0358 /// kMaxColorPlanes. 0359 /// 0360 /// \param bufferPixelType Pixel type of image buffer (see dng_tag_types.h). 0361 /// 0362 /// \param allocator dng_memory_allocator to use for allocating temporary 0363 /// buffers, etc. 0364 0365 virtual void Prepare (dng_negative &negative, 0366 uint32 threadCount, 0367 const dng_point &tileSize, 0368 const dng_rect &imageBounds, 0369 uint32 imagePlanes, 0370 uint32 bufferPixelType, 0371 dng_memory_allocator &allocator) 0372 { 0373 (void) negative; 0374 (void) threadCount; 0375 (void) tileSize; 0376 (void) imageBounds; 0377 (void) imagePlanes; 0378 (void) bufferPixelType; 0379 (void) allocator; 0380 } 0381 0382 /// Implements filtering operation from one buffer to another. Source 0383 /// and destination pixels are set up in member fields of this class. 0384 /// Ideally, no allocation should be done in this routine. 0385 /// 0386 /// \param negative The negative associated with the pixels to be 0387 /// processed. 0388 /// 0389 /// \param threadIndex The thread on which this routine is being called, 0390 /// between 0 and threadCount - 1 for the threadCount passed to Prepare 0391 /// method. 0392 /// 0393 /// \param srcBuffer Input area and source pixels. 0394 /// 0395 /// \param dstBuffer Destination pixels. 0396 /// 0397 /// \param dstArea Destination pixel processing area. 0398 /// 0399 /// \param imageBounds Total image area to be processed; dstArea will 0400 /// always lie within these bounds. 0401 0402 virtual void ProcessArea (dng_negative &negative, 0403 uint32 threadIndex, 0404 dng_pixel_buffer &srcBuffer, 0405 dng_pixel_buffer &dstBuffer, 0406 const dng_rect &dstArea, 0407 const dng_rect &imageBounds) = 0; 0408 0409 virtual void Apply (dng_host &host, 0410 dng_negative &negative, 0411 AutoPtr<dng_image> &image); 0412 0413 }; 0414 0415 /*****************************************************************************/ 0416 0417 /// \brief Class to represent an in-place (i.e., pointwise, per-pixel) opcode, 0418 /// such as a global tone curve. 0419 0420 class dng_inplace_opcode: public dng_opcode 0421 { 0422 0423 protected: 0424 0425 dng_inplace_opcode (uint32 opcodeID, 0426 uint32 minVersion, 0427 uint32 flags); 0428 0429 dng_inplace_opcode (uint32 opcodeID, 0430 dng_stream &stream, 0431 const char *name); 0432 0433 public: 0434 0435 /// The pixel data type of this opcode. 0436 0437 virtual uint32 BufferPixelType (uint32 imagePixelType) 0438 { 0439 return imagePixelType; 0440 } 0441 0442 /// The adjusted bounds (processing area) of this opcode. It is limited to 0443 /// the intersection of the specified image area and the GainMap area. 0444 0445 virtual dng_rect ModifiedBounds (const dng_rect &imageBounds) 0446 { 0447 return imageBounds; 0448 } 0449 0450 /// Startup method called before any processing is performed on pixel areas. 0451 /// It can be used to allocate (per-thread) memory and setup tasks. 0452 /// 0453 /// \param negative The negative object to be processed. 0454 /// 0455 /// \param threadCount Total number of threads that will be used for 0456 /// processing. Less than or equal to MaxThreads. 0457 /// 0458 /// \param tileSize Size of source tiles which will be processed. (Not all 0459 /// tiles will be this size due to edge conditions.) 0460 /// 0461 /// \param imageBounds Total size of image to be processed. 0462 /// 0463 /// \param imagePlanes Number of planes in the image. Less than or equal to 0464 /// kMaxColorPlanes. 0465 /// 0466 /// \param bufferPixelType Pixel type of image buffer (see dng_tag_types.h). 0467 /// 0468 /// \param allocator dng_memory_allocator to use for allocating temporary 0469 /// buffers, etc. 0470 0471 virtual void Prepare (dng_negative &negative, 0472 uint32 threadCount, 0473 const dng_point &tileSize, 0474 const dng_rect &imageBounds, 0475 uint32 imagePlanes, 0476 uint32 bufferPixelType, 0477 dng_memory_allocator &allocator) 0478 { 0479 (void) negative; 0480 (void) threadCount; 0481 (void) tileSize; 0482 (void) imageBounds; 0483 (void) imagePlanes; 0484 (void) bufferPixelType; 0485 (void) allocator; 0486 } 0487 0488 /// Implements image processing operation in a single buffer. The source 0489 /// pixels are provided as input to the buffer, and this routine 0490 /// calculates and writes the destination pixels to the same buffer. 0491 /// Ideally, no allocation should be done in this routine. 0492 /// 0493 /// \param negative The negative associated with the pixels to be 0494 /// processed. 0495 /// 0496 /// \param threadIndex The thread on which this routine is being called, 0497 /// between 0 and threadCount - 1 for the threadCount passed to Prepare 0498 /// method. 0499 /// 0500 /// \param buffer Source and Destination pixels. 0501 /// 0502 /// \param dstArea Destination pixel processing area. 0503 /// 0504 /// \param imageBounds Total image area to be processed; dstArea will 0505 /// always lie within these bounds. 0506 0507 virtual void ProcessArea (dng_negative &negative, 0508 uint32 threadIndex, 0509 dng_pixel_buffer &buffer, 0510 const dng_rect &dstArea, 0511 const dng_rect &imageBounds) = 0; 0512 0513 virtual void Apply (dng_host &host, 0514 dng_negative &negative, 0515 AutoPtr<dng_image> &image); 0516 0517 }; 0518 0519 /*****************************************************************************/ 0520 0521 #endif 0522 0523 /*****************************************************************************/