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 /*****************************************************************************/